How to keep Unit tests and Integrations tests separate in pytest
According to Wikipedia and various articles it is best practice to divide tests into Unit tests (run first) and Integration tests (run second), where Unit tests are typically very fast and should be run with every build in a CI environment, however Integration tests take longer to run and should be more of a daily run.
Is there a way to divide these in pytest? Most projects don't seem to have multiple test folders, so is there a way to make sure I only run Unit, Integration or both according to the situtation (CI vs daily builds)? When calculating test coverage, I assume I will have to run both.
Am I going about this the right way in attempting to divide the tests into these categories? Is there a good example somewhere of a project that has done this?
Yes, you can mark tests with the pytest.mark
decorator.
Example:
def unit_test_1():
# assert here
def unit_test_2():
# assert here
@pytest.mark.integtest
def integration_test():
# assert here
Now, from the command line, you can run pytest -m "not integtest"
for only the unit tests, pytest -m integtest
for only the integration test and plain pytest
for all.
(You can also decorate your unit tests with pytest.mark.unit
if you want, but I find that slightly tedious/verbose)
See the documentation for more information.
You can also structurally separate unit and integration tests into specific directories. Here is a sample file structure from A. Shaw's article Getting Started With Testing in Python:
With a structural approach, you:
- do not need to manually mark various tests with attributes or
@pytest.mark
. - are not limited to a specific test runner. See examples below.
Examples
Here we run various test runners on integration tests alone. See the sample project/
directory in the figure above.
With unittest
from the standard library:
λ python -m unittest discover -s tests/integration
With nose
:
λ nose tests/integration
With pytest
:
λ pytest tests/integration
Many test runners have an auto test-discovery mechanism that can find tests in sub-directories. This offers the choice to run all tests with ease, e.g.
λ cd <root_dir>
λ pytest project/