Run pytest with verbose output
pytest -v
Hide warnings
pytest -p no:warnings
Run tests that have the custom marker slow
pytest -m slow
pytest -m "not slow"
pytest -m "slow and fast"
pytest -m "slow or fast"
Run tests that have 'logged' keyword in their name
pytest -k "logged"
Prints print statements to shell
pytest -s
List test with durations, x is the number of slowest durations
pytest --durations=0
List test with durations over 1 second
pytest --durations-min=1.0
Creates a results.xml file (e.g. for Jenkins)
pytest --junitxml="BUILD\_${BUILD_NUMBER}\_results.xml"
Creates a results.html file with test results
pytest --html="results.html"
Makes the default pytest results better
pip install pytest-sugar
Run pytest without sugar
pytest -p no:sugar
Run pytest with 8 threads
pytest -n 8
Detect processors and use all threads
pytest -n auto
File starts with
[pytest]
Run pytest with these flags
adopts = -s -v
Register markers
markers =
slow
performance: with description
from pytest import mark
Skip the test
@pytest.mark.skip
Skip the test with an added reason
@pytest.mark.skip(reason="Some reason")
Skip test conditionally with an added reason
@pytest.mark.skipif(4 > 1, reason="Some reason")
Mark test expected to fail, still run it but marked as xfail instead of fail
@pytest.mark.xfail
@pytest.mark.xfail(reason="Some reason")
Custom markers, for example mark a test as 'slow'
@pytest.mark.slow
Runs the test in its own transaction that will be rolled back at the end of the test, allowing parallel testing
@pytest.mark.django_db
Mark a function as a fixture that can be used as a parameter in a test function
@pytest.fixture
Run fixture for every parameter
@fixture(params=[])
Run the test for each value in values
@pytest.mark.parametrize(varname, ["one", "two", "three"])
Same with multiple variables
@pytest.mark.parametrize("var1,var2", [(0, 1), (2, 3), (4, 5)])
Indirect=True: first run the "companies" fixture on the data before giving the data to the test
pytest.mark.parametrize("companies", [["one", "two", "three"], ["four", "five"]], indirect=True)
With ids
pytest.mark.parametrize("companies", [["one", "two", "three"], ["four", "five"]], ids=["first three", "last two"], indirect=True)
Give every function in the file this decorator
pytestmark = pytest.mark.django_db
pytestmark = [pytest.mark.django_db, pytest.mark.slow]
with pytest.raises(Exception) as e:
raise_some_exception()
assert "Some Value" == str(e.value)
assert "some value" in caplog.text
with caplog.at_level(logging.INFO):
assert "infolog" in caplog.text
from django.core import mail
assert len(mailoutbox) == 0
mail.send(...)
assert len(mailoutbox) == 1
assert mailoutbox[0].subject == "Test subject"
Change settings with settings fixture
def test_something(settings);
settings.EMAIL_BACKEND="django.core.mail.backends.locmem.EmailBackend"
Patch replaces an object with another object
def patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs):
Patch target targets where the object is being used, not where it is defined.
# db_utils.py
def db_write():
print("db_write, enter")
# utils.py
from db_utils import db_write
def foo()
print("foo, enter")
x = db_write()
return x
# test_mocking.py
from unittest.mock import patch
from utils import foo
@patch("utils.db_write", MagicMock(return_value=42))
def test_mock_out_db_write():
assert foo() == 42
Doesn't run the actual function but makes sure it is called with the given arguments
from unittest.mock import patch
with patch("path.to.function") as mocked_function:
mocked_function.assert_called_with(**kwargs)
Mock an API json response
responses.add(method=responses.GET, url="someurl", json={}, status=200)
response = request.get(url="url", headers={})
assert response.status_code == 200
response_content = json.loads(response.content)
assert response_content["somevalue"] == "somevalue
Install Allure for pytest
pip install allure-pytest
Install Allure (Mac)
brew install allure
Install Allure (Linux)
sudo apt-add-repository ppa:qameta/allure
sudo apt-get update
sudo apt-get install allure
Run pytest and create Allure json test files
pytest . --aluredir=/tmp/my_allure_results
Run Allure to display the created json test files
allure serve /tmp/my_allure/results
@fixture(params[webdriver.Chome, webdriver.Firefox]) def browser(request): driver = request.param drvr = driver() yield drvr drvr.quit()
Tox is a tool for running tests in different virtual environments. python -m pip install tox tox # creates tox.ini
[pytest]
pytest --markers # prints markers with descriptions that are documented in pytest.ini
Feature flags to use new code on only a percentage of the live database.
Use lru_cache decorator on functions that take a long time and the input-output is always the same.
@lru_cache(maxsize=256)