On Saturday, February 11, 2017, kirby urner <kirby.urner@gmail.com> wrote:
Does anyone use this pattern?:
(a) accept command line parameters if __name__ == "__main__" or (b) run unittests if no parameters passed
Something like:
if __name__ == "__main__": if len(sys.argv)==7: command_line() else: unittest.main()
I'm using this pattern with my classes, as a way of touching on both passing arguments from the command line (with nod to argparse for POSIX compliance), and self-contained testing.
https://en.wikipedia.org/wiki/POSIX - https://en.wikipedia.org/wiki/Exit_status - https://en.wikipedia.org/wiki/Exit_(system_call) - https://docs.python.org/3/library/signal.html#example - https://docs.python.org/3/library/atexit.html#atexit-example * - https://docs.python.org/3/library/sys.html#sys.exit returncode = range(0,128)[0] sys.exit(returncode) # https://docs.python.org/3.5/library/unittest.html#unittest.main sys.exit(unittest.main(exit=False)) # Running tests from the CLI def _main(argv=None) argv = list(argv) idx = argv.index('-t') if idx != -1: test_args = argv[idx+1:] argv.pop('-t') - https://docs.python.org/2.7/library/optparse.html - https://docs.python.org/3/library/argparse.html - http://click.pocoo.org/5/ In order to make main() testable, I like the following signature: def main(argv=None, stdin=None, stdout=None): argv = list(argv) # optparse/argparse output = func() return 0 def _main(): sys.exit(main(sys.argv)) if __name__ == "__main__": _main() def test_main_help(): retcode = _main(['-h',]) assert retcode == 0 retcode = _main(['--help',]) assert retcode == 0 ... in order to get test coverage for the main() entrypoint. Additional advantages of defining _main() and main(): - python -m modulename # should sys.exit - __main__.py - __init__.py:__main__ - setup.py console_script entry_points # should sys.exit - setup.py: 'scriptname = modulename:main' - https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script...
Maybe this would be better with doctest instead. I could do another version....
Pytest | homepage: http://pytest.org | pypi: https://pypi.python.org/pypi/pytest | src: https://github.com/pytest-dev/pytest | docs: http://doc.pytest.org/en/latest/contents.html http://doc.pytest.org/en/latest/talks.html - Fixtures: - @pytest.fixture(scope=) - http://docs.pytest.org/en/latest/fixture.html - http://doc.pytest.org/en/latest/fixture.html#fixture-parametrize - Parametrizations: - @pytest.mark.parametrized - http://doc.pytest.org/en/latest/parametrize.html - Assertions - assert (with regular 'assert') - note that asserts are compiled out with 'python -O' - with pytest.raises - http://doc.pytest.org/en/latest/assert.html - Plugins - http://docs.pytest.org/en/latest/plugins.html#installing-external-plugins-se... - https://plugincompat.herokuapp.com/ - https://pivotfinland.com/pytest-sugar/ - https://github.com/zonca/pytest-ipynb (include 'assert' in Jupyter Notebook cells) - https://github.com/matplotlib/pytest-mpl - https://github.com/kevin1024/pytest-httpbin (great for learning HTTP w/ e.g. requests) - https://github.com/getsentry/pytest-responses (mock requests w/ responses) - https://github.com/manahl/pytest-plugins (shutil.Workspace.__exit__, .__del__) - https://github.com/pytest-dev/pytest-runner ($ python setup.py pytest ) - https://github.com/westurner?tab=stars&q=pytest
Example: https://github.com/4dsolutions/Python5/blob/master/tetravolume.py
- unitest.main(exit=True) is the default - @pytest.mark.parametrized - sage - https://github.com/sagemath/sage/tree/master/src/sage/geometry - http://doc.sagemath.org/html/en/reference/geometry/ - http://doc.sagemath.org/html/en/reference/geometry/sage/geometry/polyhedron/... - http://doc.sagemath.org/html/en/reference/plot3d/#backends {Tachyon, Three.js} - http://doc.sagemath.org/html/en/reference/plot3d/sage/plot/plot3d/base.html - http://doc.sagemath.org/html/en/reference/plot3d/sage/plot/plot3d/platonic.h... - https://github.com/sagemath/sage/blob/master/src/sage/plot/polygon.py Polygon
Kirby