在差异上运行覆盖率和 linting 报告
项目描述
自动查找需要测试覆盖的差异行。还可以找到存在违规的差异行(根据 pycodestyle、pyflakes、flake8 或 pylint 等工具)。这在代码审查期间用作代码质量指标。
概述
差异覆盖率是测试覆盖的新行或修改行的百分比。这为代码审查提供了一个清晰且可实现的标准:如果您触及一行代码,则应覆盖该行。代码覆盖率是每个开发人员的责任!
diff-cover命令行工具将XML 覆盖率报告与git diff的输出进行比较。然后它报告差异中行的覆盖率信息。
目前,diff-cover要求:
您正在使用git进行版本控制。
您的测试运行程序会生成 Cobertura、Clover 或 JaCoCo XML 格式的覆盖率报告。
支持的 XML 覆盖率报告可以使用许多覆盖率工具生成,包括:
diff-cover设计为可扩展的。如果您有兴趣添加对其他版本控制系统或覆盖率报告格式的支持,请参阅下文以获取有关如何贡献的信息!
安装
要安装最新版本:
pip install diff_cover
要安装开发版本:
git clone https://github.com/Bachmann1234/diff-cover.git
cd diff-cover
python setup.py install
入门
将当前工作目录设置为git存储库。
在覆盖范围内运行您的测试套件并生成 [Cobertura、Clover 或 JaCoCo] XML 报告。例如,使用pytest-cov:
pytest --cov --cov-report=xml
这将在当前工作目录中创建一个coverage.xml文件。
注意:如果您使用不同的覆盖率生成器,则需要使用不同的命令来生成覆盖率 XML 报告。
运行diff-cover:
diff-cover coverage.xml
这会将当前的git分支与origin/main进行比较,并将差异覆盖率报告打印到控制台。
您还可以生成报告的 HTML、JSON 或 Markdown 版本:
diff-cover coverage.xml --html-report report.html
diff-cover coverage.xml --json-report report.json
diff-cover coverage.xml --markdown-report report.md
多个 XML 覆盖率报告
如果一个人有来自多个测试套件的多个 xml 报告,您可以通过运行diff-cover并将多个覆盖率报告作为参数来获得组合覆盖率报告(如果一行被任何 xml 报告覆盖,则将其计为已覆盖). 您可以指定任意数量的覆盖率报告:
diff-cover coverage1.xml coverage2.xml
质量覆盖
您也可以通过运行diff-quality来使用 diff-cover 查看有关 diff 的质量报告 。
diff-quality --violations=<tool>
其中工具是要使用的质量检查器。目前支持 pycodestyle、pyflakes、 flake8、pylint、checkstyle、checkstylexml,但可以(并且应该!)支持更多的检查器。 请参阅“为新的质量检查器添加diff-quality支持”部分。
注意:没有办法从diff-quality运行findbugs ,因为它在生成的 java 字节码上运行,应该集成到构建框架中。
像diff-cover一样,可以使用 HTML、JSON 或 Markdown 报告生成
diff-quality --violations=<tool> --html-report report.html
diff-quality --violations=<tool> --json-report report.json
diff-quality --violations=<tool> --markdown-report report.md
如果您已经使用pycodestyle、pyflakes、flake8、 pylint、checkstyle、checkstylexml或findbugs生成报告,则可以将报告传递给diff-quality。这比让diff-quality重新运行 pycodestyle、pyflakes、flake8、pylint、checkstyle或checkstylexml更有效。
# For pylint < 1.0
pylint -f parseable > pylint_report.txt
# For pylint >= 1.0
pylint --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" > pylint_report.txt
# Use the generated pylint report when running diff-quality
diff-quality --violations=pylint pylint_report.txt
# Use a generated pycodestyle report when running diff-quality.
pycodestyle > pycodestyle_report.txt
diff-quality --violations=pycodestyle pycodestyle_report.txt
请注意,您必须使用-f可解析选项为低于 1.0 的 pylint 版本 生成pylint报告,为 >= 1.0 的版本生成--msg-template选项。
diff-quality还将接受多个pycodestyle、 pyflakes、 flake8或pylint报告:
diff-quality --violations=pylint report_1.txt report_2.txt
如果您需要传递其他选项,您可以使用选项标志
diff-quality --violations=pycodestyle --options="--exclude='*/migrations*' --statistics" pycodestyle_report.txt
比较分支
默认情况下,diff-cover将当前分支与origin/main进行比较。要指定不同的比较分支:
diff-cover coverage.xml --compare-branch=origin/release
失败
如果报告质量/覆盖率百分比低于某个阈值,要让diff-cover和diff-quality返回非零状态代码,请指定 fail-under 参数
diff-cover coverage.xml --fail-under=80
diff-quality --violations=pycodestyle --fail-under=80
如果覆盖率或质量分数低于 80%,上述将返回非零状态。
排除/包含路径
diff-cover和diff-quality都可以显式排除路径,而仅diff-quality支持包含(自 5.1.0 起)。
exclude 选项与fnmatch一起使用,与glob一起使用。这两个选项都可以使用多个值。包含选项应该用双引号括起来,以防止 shell 通配符。它们也应该相对于当前的 git 目录。
diff-cover coverage.xml --exclude setup.py
diff-quality --violations=pycodestyle --exclude setup.py
diff-quality --violations=pycodestyle --include project/foo/**
对每个更改的文件执行以下操作:
检查是否指定了任何包含模式
如果是,请检查更改的文件是否是至少一个包含模式的一部分
检查文件是否属于任何排除模式
根据 git 中的文件状态忽略/包含
diff-cover和diff-quality都允许用户忽略和包含基于 git 状态的文件:staged、unstaged、untracked:
--ignore-staged:忽略所有暂存文件(默认包括它们)
--ignore-unstaged:忽略所有未暂存的文件(默认包括它们)
--include-untracked:包括所有未跟踪的文件(默认忽略它们)
静音模式
diff-cover和diff-quality都支持默认禁用的安静模式。可以使用-q / --quiet标志启用它:
diff-cover coverage.xml -q
diff-quality --violations=pycodestyle -q
如果启用,该工具将仅打印错误和失败,但不打印信息或警告消息。
配置文件
这两种工具都允许用户使用–config-file / -c在配置文件中指定选项:
diff-cover coverage.xml --config-file myconfig.toml
diff-quality --violations=pycodestyle --config-file myconfig.toml
目前,仅支持 TOML 文件。请注意,仅支持非强制性选项。如果在配置文件和命令行中指定了选项,则使用命令行的值。
TOML 配置
解析器只会对以.toml结尾的配置文件做出反应。要使用它,请安装带有额外要求toml的diff-cover。
选项名称与命令行上的相同,但所有破折号都应为下划线。如果一个选项可以被指定多次,那么配置值应该被指定为一个列表。
[tool.diff_cover]
compare_branch = <s>"origin/feature"</s>
quiet = true
[tool.diff_quality]
compare_branch = <s>"origin/feature"</s>
ignore_staged = true
故障排除
问题:diff-cover总是报告:“此 diff 中没有包含覆盖信息的行。”
解决方案:diff-cover将覆盖率 XML 报告中的源文件与git diff中的源文件匹配。因此,文件的相对路径匹配很重要。如果您使用coverage.py 生成覆盖率 XML 报告,请确保 从同一工作目录运行diff-cover 。
问题:GitDiffTool._execute()引发错误:
fatal: ambiguous argument 'origin/main...HEAD': unknown revision or path not in the working tree.
众所周知,在Travis CI中运行diff-cover时会发生这种情况
解决方案:在运行diff-cover之前获取远程主分支:
git fetch origin master:refs/remotes/origin/main
问题:差异质量报告“diff_cover.violations_reporter.QualityReporterError:未找到配置文件,使用默认配置”
解决方案:您的项目需要一个pylintrc文件。提供这个文件(它可以是空的)并且diff-quality应该没有问题地运行。
问题:差异质量报告“未安装质量工具”
解决方案:diff-quality假设您已经安装了您希望针对您的 diff 运行的工具。如果您没有它,请使用您最喜欢的包管理器安装它。
问题:diff-quality报告没有质量问题
解决方案:您可以使用类似diff-quality --violations foo *.py的模式。最后一个参数不用于指定文件,而是用于质量工具报告。删除它以解决问题
执照
此存储库中的代码在 Apache 2.0 许可下获得许可。有关详细信息,请参阅LICENSE.txt。
如何贡献
贡献是非常受欢迎的。最简单的方法是 fork 这个 repo,然后从你的 fork 发出 pull request。
注意:diff-quality支持插件模型,因此可以集成新工具而无需更改此 repo。 请参阅“为新的质量检查器添加diff-quality支持”部分。
为发展做准备
这个项目是用诗歌管理的,可以用pip安装。 诗歌管理 python 虚拟环境并组织依赖项。它还打包了这个项目。
pip install poetry
poetry install
我还建议在之后运行此命令。这将使 git blame 忽略格式化整个代码库的提交。
git config blame.ignoreRevsFile .git-blame-ignore-revs
为新的质量检查器添加diff-quality支持
添加对新质量检查器的支持很简单。diff-quality支持使用流行的 Python 插件包的插件。
如果质量检查器已经作为 Python 包实现,那就太好了!如果没有, 请创建一个 Python 包 来托管插件实现。
在 Python 包的setup.py文件中,定义插件的入口点,例如
setup(
...
entry_points={
'diff_cover': [
'sqlfluff = sqlfluff.diff_quality_plugin'
],
},
...
)
笔记:
入口点的字典键必须命名为diff_cover
该值必须采用TOOL_NAME = YOUR_PACKAGE.PLUGIN_MODULE格式
安装包后,diff-quality使用此信息根据提供给diff-quality命令的--violations选项的工具名称查找工具包和模块 ,例如:
$ diff-quality --violations sqlfluff
插件实现将类似于下面的示例。这是一个基于工作插件实现的简化示例。
from diff_cover.hook import hookimpl as diff_cover_hookimpl
from diff_cover.violationsreporters.base import BaseViolationReporter, Violation
class SQLFluffViolationReporter(BaseViolationReporter):
supported_extensions = ['sql']
def __init__(self):
super(SQLFluffViolationReporter, self).__init__('sqlfluff')
def violations(self, src_path):
return [
Violation(violation.line_number, violation.description)
for violation in get_linter().get_violations(src_path)
]
def measured_lines(self, src_path):
return None
@staticmethod
def installed():
return True
@diff_cover_hookimpl
def diff_cover_report_quality():
return SQLFluffViolationReporter()
重要笔记:
diff-quality正在寻找插件功能:
位于setup.py入口点中列出的包的模块中。
标有@diff_cover_hookimpl装饰器
名为diff_cover_report_quality。(这将它与diff_cover可能支持的任何其他插件类型区分开来。)
该函数应返回具有以下属性和方法的对象:
带有支持的文件扩展名列表的supported_extensions属性
违规()函数,返回指定src_path的违规对象列表。有关此函数和其他可能的报告相关方法的更多详细信息,请参阅此处的BaseViolationReporter类 。
特别感谢
向 diff-cover Will Daly的原作者和 diff-quality Sarina Canelake的原作者大喊。
最初在edX的支持下创建。