Skip to main content

neatest

Easy-to-use unit test runner.

  • Simplifies discovery of unittest.TestCase tests in the project
  • Runs tests with standard unittest
  • Testing can be started from the shell with a single-word command: neatest
  • Testing can be customized by python scripts calling neatest.run(...)

neatest can replace many runs of python -m unittest discover ... command. The priority for neatest is full compatibility and interchangeability with the standard unittest. Tests that can be run from neatest can also be run with unittest without any project modification.


Supports Python 3.7+ on Linux, macOS and Windows.

Install

pip3 install neatest

Project layout

neatest discovers all classes inherited from unittest.TestCase within the project. Test cases can be placed in any .py file inside any directory. If you prefer to keep test cases in the "tests" directory with filenames starting with "test", they will be discovered, because they are also "any files in any directory".

You can use a simple project layout:

my_simple_project
    __init__.py     # tests can be placed here
    test_a.py       # tests can be placed here
    test_b.py       # tests can be placed here
    anything.py     # tests can be placed here

or a project with multiple packages:

my_complex_project
    package_a
        __init__.py         # tests can be placed here
        any_files.py        # tests can be placed here
        can_contain.py      # tests can be placed here
        tests_inside.py     # tests can be placed here
        ...
    package_b
        __init__.py         # tests can be placed here
        ...
    tests  
        __init__.py         # tests can be placed here
        test_something.py   # tests can be placed here
        test_anything.py    # tests can be placed here        

Subdirectories must be importable as packages from the project directory.

They are importable, when you can

$ cd my_complex_project
$ python3 

and then in Python

import package_a
import package_b
import tests 

Run

Run tests from command line

$ cd my_complex_project
$ neatest
Package "package_a" contains 3 tests
Package "package_b" contains 4 tests
Package "tests" contains 16 tests
.....
----------------------------------------------------------------------
Ran 23 tests in 2.947s

OK

Add some options:

$ cd my_complex_project
$ neatest --start-directory tests --verbose

See all possible options:

$ neatest --help

Run tests from .py script

Create a script

For example, run_tests.py:

import neatest
neatest.run()

Run the script

$ cd my_complex_project
$ python3 path/to/run_tests.py

The idea is to use single .py script to run the tests (instead of .sh, .bat or .cfg). Python scripts are readable, and they are portable as the Python itself.

You can specify all the options available to neatest command-line tool as arguments to neatest.run method:

import neatest
neatest.run(start_directory="tests",
            verbosity=neatest.Verbosity.verbose)

Arguments

tests_require

You can specify dependencies to be installed with pip install before testing. These dependencies are presumably missing from requirements.txt and setup.py as they are not needed in production.

neatest.run(tests_require=['requests', 'lxml']) 
$ neatest -r requests -r lxml

This is the equivalent of the deprecated argument tests_require from setuptools.setup.

warnings

By default, warnings caught during testing are printed to the stdout.

warnings: ignore

In this mode warnings will not be displayed.

neatest.run(warnings=neatest.Warnings.ignore)
$ neatest --warnings ignore

warnings: fail

In this mode warnings will be treated as errors. If at least one warning appears during testing, it will cause the testing to fail (with exception or non-zero return code).

neatest.run(warnings=neatest.Warnings.fail)
$ neatest --warnings fail

Test discovery

Filenames

neatest searches for tests in all *.py files.

The same can be achieved with standard unittest like this:

$ python3 -m unittest discover -p "*.py"

Directories

neatest assumes, that the current directory is the project directory. It is the base directory for all imports.

If the start_directory are not specified, neatest will find all the packages inside the project directory and will run tests for each of them.

my_project
    package_a               # tests in package_a will be discovered
        __init__.py
    package_b               # tests in package_b will be discovered
        __init__.py
    package_c               # tests in package_c will be discovered
        __init__.py
        subpackage          # subpackage is a part of package_c 
            __init__.py     # so tests will be discovered
            ...
    subdir                  # subdir is not a package
        package_d           # tests in package_d will NOT be discovered  
            __init__.py     # because package_d is not importable    
  setup.py

So the commands

$ cd my_project
$ neatest

will run the same tests as

$ cd my_project
$ python3 -m unittest discover -t . -s package_a -p "*.py"
$ python3 -m unittest discover -t . -s package_b -p "*.py"
$ python3 -m unittest discover -t . -s package_c -p "*.py"

Release files for neatest 3.9.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for neatest 3.9.1
File Size Uploaded
neatest-3.9.1.tar.gz 10.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for neatest 3.9.1
File Interpreter ABI Platform
neatest-3.9.1-py3-none-any.whl Python 3 none any Details

Total release size: 19.6 kB

Release files / neatest-3.9.1.tar.gz

Download URL neatest-3.9.1.tar.gz
Size 10.4 kB
Tags Source
SHA-256 checksum
How to use checksums
ffdda5de0cf09747045a471913c8d9703288a1029f7fc82c6ce619cffe2b4643
BLAKE2b-256 checksum
How to use checksums
0f89668252a20e119bea52dbfa2779b89bc7fa1d6e1bffbaec13d75ac5442ade
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.10.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.10.2

Release files / neatest-3.9.1-py3-none-any.whl

Download URL neatest-3.9.1-py3-none-any.whl
Size 9.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
46ef3fe1fae7c7106a8f7add2d16e30de1097daf5b182aa46a3f66bd8d0a165b
BLAKE2b-256 checksum
How to use checksums
969b80bdf6dc909c6e6baf14437e353f0397b934d68bb0eea3e0cddb0c4f8047
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.10.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.10.2

Release history Release notifications | RSS feed

This release

3.9.1 This release

2 release files

3.9.0

2 release files

3.8.0

2 release files

3.7.2

2 release files

3.7.1

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.19

2 release files

0.0.18

2 release files

0.0.17

2 release files

0.0.16

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page