neatest


Nameneatest JSON
Version 3.9.1 PyPI version JSON
download
home_pagehttps://github.com/rtmigo/neatest_py#neatest
SummaryDiscovers and runs unit tests with a single-word command.
upload_time2022-02-04 23:29:17
maintainer
docs_urlNone
authorArtёm IG
requires_python>=3.7
licenseMIT
keywords unit tests unittest unit-tests testing discovery test ci
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # [neatest](https://github.com/rtmigo/neatest_py#readme)

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

``` bash
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

``` bash
$ cd my_complex_project
$ python3 
```

and then in Python

``` python3
import package_a
import package_b
import tests 
```

# Run

## Run tests from command line

``` bash
$ 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:

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

See all possible options:

``` bash
$ neatest --help
```


## Run tests from .py script

#### Create a script

For example, `run_tests.py`:

``` python3
import neatest
neatest.run()
```

#### Run the script

``` bash
$ 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:

``` python3
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.

``` python
neatest.run(tests_require=['requests', 'lxml']) 
```

``` bash
$ 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.

``` python
neatest.run(warnings=neatest.Warnings.ignore)
```
``` bash
$ 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).

``` python
neatest.run(warnings=neatest.Warnings.fail)
```
``` bash
$ neatest --warnings fail
```


# Test discovery

## Filenames

`neatest` searches for tests in all `*.py` files.

The same can be achieved with standard `unittest` like this:

``` bash
$ 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

``` bash
$ cd my_project
$ neatest
```

will run the same tests as

``` bash
$ 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"
```





            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/rtmigo/neatest_py#neatest",
    "name": "neatest",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "unit,tests,unittest,unit-tests,testing,discovery,test,ci",
    "author": "Art\u0451m IG",
    "author_email": "ortemeo@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/0f/89/668252a20e119bea52dbfa2779b89bc7fa1d6e1bffbaec13d75ac5442ade/neatest-3.9.1.tar.gz",
    "platform": "",
    "description": "# [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\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Discovers and runs unit tests with a single-word command.",
    "version": "3.9.1",
    "project_urls": {
        "Homepage": "https://github.com/rtmigo/neatest_py#neatest"
    },
    "split_keywords": [
        "unit",
        "tests",
        "unittest",
        "unit-tests",
        "testing",
        "discovery",
        "test",
        "ci"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "969b80bdf6dc909c6e6baf14437e353f0397b934d68bb0eea3e0cddb0c4f8047",
                "md5": "b80f00e7e1ed08c7c2877807a465fd03",
                "sha256": "46ef3fe1fae7c7106a8f7add2d16e30de1097daf5b182aa46a3f66bd8d0a165b"
            },
            "downloads": -1,
            "filename": "neatest-3.9.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b80f00e7e1ed08c7c2877807a465fd03",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 9164,
            "upload_time": "2022-02-04T23:29:16",
            "upload_time_iso_8601": "2022-02-04T23:29:16.049877Z",
            "url": "https://files.pythonhosted.org/packages/96/9b/80bdf6dc909c6e6baf14437e353f0397b934d68bb0eea3e0cddb0c4f8047/neatest-3.9.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0f89668252a20e119bea52dbfa2779b89bc7fa1d6e1bffbaec13d75ac5442ade",
                "md5": "427eb5033bd7013550874b403dd48c75",
                "sha256": "ffdda5de0cf09747045a471913c8d9703288a1029f7fc82c6ce619cffe2b4643"
            },
            "downloads": -1,
            "filename": "neatest-3.9.1.tar.gz",
            "has_sig": false,
            "md5_digest": "427eb5033bd7013550874b403dd48c75",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 10432,
            "upload_time": "2022-02-04T23:29:17",
            "upload_time_iso_8601": "2022-02-04T23:29:17.798148Z",
            "url": "https://files.pythonhosted.org/packages/0f/89/668252a20e119bea52dbfa2779b89bc7fa1d6e1bffbaec13d75ac5442ade/neatest-3.9.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-02-04 23:29:17",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "rtmigo",
    "github_project": "neatest_py#neatest",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "neatest"
}
        
Elapsed time: 0.12193s