pytest
Links
Install
pip install pytest
Assert
Extra data:
assert a % 2 == 0, "value was odd, should be even"
Exception:
import pytest
with pytest.raises(RuntimeError) as excinfo:
def f():
f()
f()
assert 'maximum recursion' in str(excinfo.value)
Multi-line string:
To compare a multi-line string with newlines and lots of spaces…
def _clean(x):
result = textwrap.dedent(x)
result = " ".join(result.split())
return result
Parametrize
@pytest.mark.parametrize("state,expected", [
(Document.SYNCED, True),
(Document.MODIFIED, False),
(Document.NEW, True),
])
def test_can_edit(state, expected):
Parameters
Stop on first failure:
pytest -x
Disable capturing:
pytest -s
# no stdout or stderr
pytest -x --show-capture=no
# no stderr
pytest -x --show-capture=stdout
Select tests:
pytest -k test_simple
# to select a function in a module, remove '-k'
pytest dash/tests/test_view.py::test_document_detail
Modify traceback:
pytest -x --tb=short
For more information, see Modifying Python traceback printing
Debug
To use pdb
, then:
import pytest
pytest.set_trace()
To use ipdb
, then run with the -s
parameter… If you don’t do this,
you will get the following nasty/misleading error:
AttributeError: DontReadFromInput instance has no attribute 'encoding'
Diff
To display more data in the diff (for dict
and sequences), use
Diff or use the simpler assert with the assert statement
syntax e.g:
assert {'data': ['message']} == response.data
Issues
I had this error: IndexError: list index out of range. To solve the issue:
pytest -x --tb=native
Mark
import pytest
@pytest.mark.skipif(date.today() < date(2014, 9, 5),
reason='cannot test this for a couple of days...')
def test_contact_template(self):
pass
Discovery
Conventions for Python test discovery
test_*.py
or*_test.py
files, imported by their package name.Test
prefixed test classes (without an__init__
method).test_
prefixed test functions or methods are test items.
Plugins
Coverage
https://pypi.python.org/pypi/pytest-cov:
pip install pytest-cov
pytest --cov .
Note
The .
is important. This needs to be the folder you want
coverage to report on.
Django app example:
pytest -x --reuse-db --cov-report html --cov job
Django
I have been using this plugin:
pip install pytest-django
To write a test which needs to access the database:
import pytest
@pytest.mark.django_db
def test_audit():
# write your test
To run the Django tests, make sure DJANGO_SETTINGS_MODULE
is defined,
then:
pytest -x
The -x
option stops the tests on the first failure.
To print
or use ipdb
, use the -s
option:
pytest -x -s
# or
import pytest
pytest.set_trace()
Note
pytest
will cache the database structure to speed up test runs. To
re-initialise the database, use the --create-db
option:
pytest -x --create-db
Flakes
pip install pytest-flakes
pytest --flakes
PEP 8
http://pypi.python.org/pypi/pytest-pep8/:
pip install pytest-pep8
pytest --pep8
# to clear the cache
pytest --pep8 --clearcache
Sugar
http://pivotfinland.com/pytest-sugar/:
pip install pytest-sugar
Nothing else to do.
Time
Freeze time! https://github.com/ktosiek/pytest-freezegun
Watch
https://pypi.python.org/pypi/pytest-watch/:
pip install pytest-watch
Usage:
py.test.watch
# or ptw