I have the following code in 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()
If I call this in the command line, it works:
python test.py --text=hi!
>>hi!
If I want to test my code, I would use:
from click.testing import CliRunner
runner = CliRunner()
result = runner.invoke(test.say, ['--text=blablabla'])
assert result.output == 'blablabla
This works too.
However, if I run my test through coverage.py, I see that the code under if __name__ == "__main__":
is not tested. Is there a way to achieve that?
Maybe you didn't realize that the codes below __name__ == "__main__"
was never invoked by your test code
result = runner.invoke(test.say, ['--text=blablabla'])
Even if you modify the "test.py" like this, your test will not complain.
if __name__ == "__main__":
raise RuntimeError("Something is wrong")
say()
The reason is that __name__ == "__main__"
will be false if the module file "test.py" is imported. So any codes inside the if
clause will be ignored.
To get 100% coverage, run the command directly
$ coverage run test.py --text=blablabla
blablabla
$ coverage report
Name Stmts Miss Cover
-----------------------------
test.py 6 0 100%
This is what the standard library module runpy
is for. See: https://docs.python.org/3/library/runpy.html#runpy.run_module
__name__ != "__main__"
if you're calling this from a different module.
What should work is:
import click
@click.command()
@click.option('--text', default='hello world', help='Text to display.')
def say(text):
print(text)
say()
See this other SO answer if you don't want to do it this way.: https://stackoverflow.com/a/5850364/10813463
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.