如何使用 click、coverage.py 和 Tox 测试 Python CLI 程序?

twb*_*mer 3 python code-coverage coverage.py python-click

我正在使用click开发一个 CLI 程序,我想开始添加一些使用coverage.py进行代码覆盖分析的测试。

我认为实现测试的一个好方法是使用子进程运行 CLI 本身。然而,coverage.py 报告零代码覆盖率,大概是因为子进程产生的 Python 实例没有coverage.py 检测。

我发现这个链接说我可以sitecustomize.py在我的 PYTHONPATH 中放置一个文件以始终强制 Python 开始覆盖率测量,但我正在使用 Tox 创建一个 venv 并运行测试。我找不到任何处理此问题的 Tox 设置。

我发现这个答案是说我应该只是运行通过我的CLI coverage run,但它看起来像,如果给一个Python脚本的路径,只有工作,我试图通过定义的入口点运行我的CLI setup.py。即我必须将测试代码中的所有命令行从myprogram更改为coverage run myprogram/cli/cli.py。我宁愿不这样做,因为这不是我期望用户运行程序的方式。

所以看起来两个选项是:

  1. 找出一种sitecustomize.py在 Tox 环境中工作的方法,或者

  2. 测试代码中的所有命令行都使用脚本路径而不是入口点(从长远来看可能更容易,但会使测试变得更加脆弱和难以理解)。想知道是否还有什么我遗漏的。

Ste*_*uch 5

CliRunner和适当的单元测试框架是要走的路。下面是一个例子设置PyTest其使用PyTest覆盖插件

test_click.py

from click.testing import CliRunner

from click_prog import hello


def test_hello_world():

    runner = CliRunner()
    result = runner.invoke(hello, ['--opt', 'An Option', 'An Arg'])
    assert result.exit_code == 0
    assert result.output == 'Opt: An Option  Arg: An Arg\n'

    result = runner.invoke(hello, ['An Arg'])
    assert result.exit_code == 0
    assert result.output == 'Opt: None  Arg: An Arg\n'


if __name__ == '__main__':
    test_hello_world()
Run Code Online (Sandbox Code Playgroud)

click_prog.py

import click
import sys


@click.command()
@click.option('--opt')
@click.argument('arg')
def hello(arg, opt):
    """A Simple program"""
    click.echo('Opt: {}  Arg: {}'.format(opt, arg))


if __name__ == '__main__':
    hello(sys.argv[1:])
Run Code Online (Sandbox Code Playgroud)

pytest.ini

[pytest]

# -- recommended but optional:
# python_files = tests.py test_*.py *_tests.py
Run Code Online (Sandbox Code Playgroud)

检测结果:

===================== test session starts =====================
platform darwin -- Python 3.6.5, pytest-3.7.1, py-1.5.4, pluggy-0.7.1
rootdir: /Users/strauch/dev/fix_windows, inifile: pytest.ini
plugins: xdist-1.22.5, forked-0.2, cov-2.6.0
collected 1 item

test_click.py .                                         [100%]

---------- coverage: platform darwin, python 3.6.5-final-0 -----------
Name             Stmts   Miss  Cover
------------------------------------
click_prog.py        8      1    88%
test_click.py       12      1    92%
------------------------------------
TOTAL               20      2    90%


================== 1 passed in 0.07 seconds ===================
Run Code Online (Sandbox Code Playgroud)