Catego Tags: python, testing, pytest Status: draft
- a mature full-featured Python testing tool
- provides easy no-boilerplate testing
- scales from simple unit to complex functional testing
- integrated with other testing methods and tools
- extensive plugin and customization system
If you have already created your
virtualenv, download the latest pytest package and run
pip install pytest-[version].tar.gz.
Writing your tests
This is the most basic example, adapted from the Python Guide:
# content of test_sample.py def func(x): return x + 1 def test_func(): assert func(3) == 5
You only need to prefix your test function with
test_ so that Pytest can find it. A good practice is to use the name of the function you are testing after the prefix.
Mocking modules and environments
Sometimes tests need to invoke functionality which depends on global settings or which invokes code which cannot be easily tested such as network access. The monkeypatch function argument helps you to safely set/delete an attribute, dictionary item or environment variable or to modify sys.path for importing.
Monkeypatch is a module that helps you set the return values for other functions that your function depends on.
If you want to pretend that os.expanduser returns a certain directory, you can use the monkeypatch.setattr() method to patch this function before calling into a function which uses it:
# content of test_module.py import os.path def getssh(): # pseudo application code return os.path.join(os.path.expanduser("~admin"), '.ssh') def test_mytest(monkeypatch): def mockreturn(path): return '/abc' monkeypatch.setattr(os.path, 'expanduser', mockreturn) x = getssh() assert x == '/abc/.ssh'
Another useful module is Mock, which now comes with Unittest for Python 3.3 onward.
Let's mock a class, for example:
my_mock = Mock() my_mock.some_attribute = 5 my_mock.some_method = Mock() my_mock.some_method.return_value = 10
my_mock.some_method() will return 10. Similarly,
my_mock.some_attribute will return 3.
Running your tests
To run your tests, you only need run the command from your
Note: Remember to install the package you want to test beforehand with
python setup.py install.
Pytest has a 'discovery' feature to automatically find your tests within your code. This is how it works by default:
- collection starts from the initial command line arguments which may be directories, filenames or test ids.
- recurse into directories, unless they match
*_test.pyfiles, imported by their
Testprefixed test classes (without an
test_prefixed test functions or methods are test items
Note: If you run them from your package directory, and you have your
virtualenv directory in there, then
pytest will find the tests for the packages installed and run them.
Verifying test coverage
Pytest has a plugin called pytest-cov for coverage reporting of your tests. You can install this package using
For verifying centralized testing coverage in EC, we would run the following:
py.test --cov package-path/ tests-path/