使用click和pytest测试__name__ ==“ __main__”:

时间:2019-03-20 20:51:26

标签: python python-3.x code-coverage pytest coverage.py

我在test.py中有以下代码:

import click

@click.command()
@click.option('--text', default='hello world', help='Text to display.')
def say(text):

    print(text)


if __name__ == "__main__":

    say()

如果我在命令行中调用它,它将起作用:

python test.py --text=hi!
>>hi!

如果我想测试我的代码,我会使用:

from click.testing import CliRunner


runner = CliRunner()
result = runner.invoke(test.say, ['--text=blablabla'])

assert result.output == 'blablabla

这也可以。

但是,如果我通过coverage.py运行测试,则会发现if __name__ == "__main__":下的代码未经过测试。有办法实现吗?

3 个答案:

答案 0 :(得分:1)

也许您没有意识到测试代码从未调用过__name__ == "__main__"下面的代码

result = runner.invoke(test.say, ['--text=blablabla'])

即使您这样修改“ test.py”,您的测试也不会抱怨。

if __name__ == "__main__":
    raise RuntimeError("Something is wrong")
    say()

原因是如果导入模块文件“ test.py”,__name__ == "__main__"将为假。因此,if子句中的所有代码都将被忽略。

要获得100%的覆盖率,请直接运行命令

$ coverage run test.py --text=blablabla
  blablabla
$ coverage report
  Name      Stmts   Miss  Cover                                                                                                             
  -----------------------------                                                                                                             
  test.py       6      0   100%  

答案 1 :(得分:1)

这是标准库模块runpy的用途。参见:https://docs.python.org/3/library/runpy.html#runpy.run_module

答案 2 :(得分:-2)

__name__ != "__main__" if you're calling this from a different module.

应该应该起作用的是:

import click

@click.command()
@click.option('--text', default='hello world', help='Text to display.')
def say(text):

    print(text)

say()

如果您不想这样做,请参阅其他SO答案: https://stackoverflow.com/a/5850364/10813463