{"id":21206190,"url":"https://github.com/rtmigo/neatest_py","last_synced_at":"2025-07-10T08:32:54.922Z","repository":{"id":57445353,"uuid":"361016852","full_name":"rtmigo/neatest_py","owner":"rtmigo","description":"Runs unit tests with standard Python unittest module. Automates test discovery. Can be conveniently invoked from Python code","archived":false,"fork":false,"pushed_at":"2022-02-04T23:29:06.000Z","size":187,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-08T01:41:08.188Z","etag":null,"topics":["automation","package","python","test","testing","unit-testing","unittest"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/neatest","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rtmigo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-23T22:11:40.000Z","updated_at":"2022-02-09T12:00:29.000Z","dependencies_parsed_at":"2022-09-26T17:30:50.778Z","dependency_job_id":null,"html_url":"https://github.com/rtmigo/neatest_py","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fneatest_py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fneatest_py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fneatest_py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fneatest_py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rtmigo","download_url":"https://codeload.github.com/rtmigo/neatest_py/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225629877,"owners_count":17499294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","package","python","test","testing","unit-testing","unittest"],"created_at":"2024-11-20T20:54:44.683Z","updated_at":"2024-11-20T20:54:45.513Z","avatar_url":"https://github.com/rtmigo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [neatest](https://github.com/rtmigo/neatest_py#readme)\n\nEasy-to-use unit test runner. \n- Simplifies discovery of `unittest.TestCase` tests in the project \n- Runs tests with standard `unittest`\n- Testing can be started from the shell with a single-word command: `neatest`\n- Testing can be customized by python scripts calling `neatest.run(...)`\n\n`neatest` can replace many runs of `python -m unittest discover ...` command.\nThe priority for `neatest` is full compatibility and interchangeability with \nthe standard `unittest`. Tests that can be run from `neatest` can also \nbe run with `unittest` without any project modification.\n\n--------------------------------------------------------------------------------\n\nSupports Python 3.7+ on Linux, macOS and Windows.\n\n# Install\n\n``` bash\npip3 install neatest\n```\n\n# Project layout\n\n`neatest` discovers all classes inherited from `unittest.TestCase` within the\nproject. Test cases can be placed in **any .py file** inside **any directory**.\nIf you prefer to keep test cases in the \"tests\" directory with filenames\nstarting with \"test\", they will be discovered, because they are also \"any\nfiles in any directory\".\n\nYou can use a simple project layout:\n\n```\nmy_simple_project\n    __init__.py     # tests can be placed here\n    test_a.py       # tests can be placed here\n    test_b.py       # tests can be placed here\n    anything.py     # tests can be placed here\n```\n\nor a project with multiple packages:\n\n```\nmy_complex_project\n    package_a\n        __init__.py         # tests can be placed here\n        any_files.py        # tests can be placed here\n        can_contain.py      # tests can be placed here\n        tests_inside.py     # tests can be placed here\n        ...\n    package_b\n        __init__.py         # tests can be placed here\n        ...\n    tests  \n        __init__.py         # tests can be placed here\n        test_something.py   # tests can be placed here\n        test_anything.py    # tests can be placed here        \n```\n\nSubdirectories must be **importable** as packages from the project directory.\n\nThey are importable, when you can\n\n``` bash\n$ cd my_complex_project\n$ python3 \n```\n\nand then in Python\n\n``` python3\nimport package_a\nimport package_b\nimport tests \n```\n\n# Run\n\n## Run tests from command line\n\n``` bash\n$ cd my_complex_project\n$ neatest\n```\n\n```\nPackage \"package_a\" contains 3 tests\nPackage \"package_b\" contains 4 tests\nPackage \"tests\" contains 16 tests\n.....\n----------------------------------------------------------------------\nRan 23 tests in 2.947s\n\nOK\n```\n\nAdd some options:\n\n``` bash\n$ cd my_complex_project\n$ neatest --start-directory tests --verbose\n```\n\nSee all possible options:\n\n``` bash\n$ neatest --help\n```\n\n\n## Run tests from .py script\n\n#### Create a script\n\nFor example, `run_tests.py`:\n\n``` python3\nimport neatest\nneatest.run()\n```\n\n#### Run the script\n\n``` bash\n$ cd my_complex_project\n$ python3 path/to/run_tests.py\n```\n\nThe idea is to use single `.py` script to run the tests (instead of `.sh`, `.bat` or `.cfg`). \nPython scripts are readable, and they are portable as the Python itself.\n\nYou can specify all the options available to `neatest` command-line tool as \narguments to `neatest.run` method:\n\n``` python3\nimport neatest\nneatest.run(start_directory=\"tests\",\n            verbosity=neatest.Verbosity.verbose)\n```\n\n# Arguments\n\n## tests_require\n\nYou can specify dependencies to be installed with `pip install` before testing.\nThese dependencies are presumably missing from `requirements.txt` and `setup.py`\nas they are not needed in production.\n\n``` python\nneatest.run(tests_require=['requests', 'lxml']) \n```\n\n``` bash\n$ neatest -r requests -r lxml\n```\n\nThis is the equivalent of the deprecated argument `tests_require`\nfrom `setuptools.setup`.\n\n## warnings\n\nBy default, warnings caught during testing are printed to the stdout.\n\n### warnings: ignore\n\nIn this mode warnings will not be displayed.\n\n``` python\nneatest.run(warnings=neatest.Warnings.ignore)\n```\n``` bash\n$ neatest --warnings ignore\n```\n\n### warnings: fail\n\nIn this mode warnings will be treated as errors. If at least one warning appears\nduring testing, it will cause the testing to fail (with exception or non-zero\nreturn code).\n\n``` python\nneatest.run(warnings=neatest.Warnings.fail)\n```\n``` bash\n$ neatest --warnings fail\n```\n\n\n# Test discovery\n\n## Filenames\n\n`neatest` searches for tests in all `*.py` files.\n\nThe same can be achieved with standard `unittest` like this:\n\n``` bash\n$ python3 -m unittest discover -p \"*.py\"\n```\n\n## Directories\n\n`neatest` assumes, that the current directory is the project directory. It is\nthe base directory for all imports.\n\nIf the `start_directory` are not specified, `neatest` will find all the packages\ninside the project directory and will run tests for each of them.\n\n```\nmy_project\n    package_a               # tests in package_a will be discovered\n        __init__.py\n    package_b               # tests in package_b will be discovered\n        __init__.py\n    package_c               # tests in package_c will be discovered\n        __init__.py\n        subpackage          # subpackage is a part of package_c \n            __init__.py     # so tests will be discovered\n            ...\n    subdir                  # subdir is not a package\n        package_d           # tests in package_d will NOT be discovered  \n            __init__.py     # because package_d is not importable    \n  setup.py\n```\n\nSo the commands\n\n``` bash\n$ cd my_project\n$ neatest\n```\n\nwill run the same tests as\n\n``` bash\n$ cd my_project\n$ python3 -m unittest discover -t . -s package_a -p \"*.py\"\n$ python3 -m unittest discover -t . -s package_b -p \"*.py\"\n$ python3 -m unittest discover -t . -s package_c -p \"*.py\"\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtmigo%2Fneatest_py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frtmigo%2Fneatest_py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtmigo%2Fneatest_py/lists"}