简体   繁体   中英

Test if __name__ == "__main__": with click and pytest

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM