Article directory
pytest is a framework that can simplify the construction of test system and facilitate the scale expansion of test. It makes test more expressive and readable - template code is no longer necessary.
In just a few minutes, you can start a simple unit test or complex function test on your application.
1. installation
-
The command line executes the following command: pipenv install pytest==5.1.3
-
View the installed version information: pipenv run pytest --version
2. Create your first test case
It has only four lines of code:
# src/chapter-1/test_sample.py def func(x): return x + 1 def test_sample(): assert func(3) == 5
Perform the test with the following command:
λ pipenv run pytest src/chapter-1/test_sample.py ============================= test session starts ============================== platform win32 -- Python 3.7.3, pytest-5.1.3, py-1.8.0, pluggy-0.13.0 rootdir: D:\Personal Files\Projects\pytest-chinese-doc collected 1 item src\chapter-1\test_sample.py F [100%] =================================== FAILURES =================================== _________________________________ test_sample __________________________________ def test_sample(): > assert func(3) == 5 E assert 4 == 5 E + where 4 = func(3) src\chapter-1\test_sample.py:28: AssertionError ============================== 1 failed in 0.05s ===============================
pytest returns a failed test report because func(3) is not equal to 5.
3. Execute multiple test cases
Execute the pipenv run py test command, which will execute all files in the current and its subfolders named in accordance with the rules of test *. Py or * _test.py;
4. Trigger an assertion of the specified exception
Use raises to check whether the code throws a specified exception:
# src/chapter-1/test_sysexit.py import pytest def f(): # Interpreter request exit raise SystemExit(1) def test_mytest(): with pytest.raises(SystemExit): f()
When executing this test case, add the - q option to view the simplified test report:
λ pipenv run pytest -q src/chapter-1/test_sysexit.py . [100%] 1 passed in 0.01s
5. Organize multiple test cases in a class
pytest allows you to easily include multiple test cases by creating a test class:
# src/chapter-1/test_class.py class TestClass: def test_one(self): x = 'this' assert 'h' in x def test_two(self): x = 'hello' assert hasattr(x, 'check')
Now let's execute this test case:
λ pipenv run pytest -q src/chapter-1/test_class.py .F [100%] =================================== FAILURES =================================== ______________________________ TestClass.test_two ______________________________ self = <test_class.TestClass object at 0x000001D364778E48> def test_two(self): x = 'hello' > assert hasattr(x, 'check') E AssertionError: assert False E + where False = hasattr('hello', 'check') src\chapter-1\test_class.py:30: AssertionError 1 failed, 1 passed in 0.05s
From the output report, we can see:
- Test one is passed, represented by; test two is failed, represented by F;
- It can be seen from the clearing that the reason for test two failure is: false = hasattr ('Hello ',' check ');
Be careful:
The test class must conform to specific rules before pytest can discover it:
- The commands of the Test class should conform to the Test * rule;
- The test class cannot have an init method.
6. Apply for a unique temporary directory
pytest provides some built-in fixtures that can be used to request some system resources. For example, a unique temporary directory:
# src/chapter-1/test_tmpdir.py def test_needsfiles(tmpdir): print(tmpdir) assert 0
In the test case, the built-in tempdir fixture is used as a parameter. pytest will create a directory in advance and pass in a py.path.local object as an argument.
Now, let's execute this test case:
λ pipenv run pytest -q src/chapter-1/test_tmpdir.py F [100%] =================================== FAILURES =================================== _______________________________ test_needsfiles ________________________________ tmpdir = local('C:\\Users\\luyao\\AppData\\Local\\Temp\\pytest-of-luyao\\pytest-1\\test_needsfiles0') def test_needsfiles(tmpdir): print(tmpdir) > assert 0 E assert 0 src\chapter-1\test_tmpdir.py:25: AssertionError ----------------------------- Captured stdout call ----------------------------- C:\Users\luyao\AppData\Local\Temp\pytest-of-luyao\pytest-1\test_needsfiles0 1 failed in 0.05s
You can use the following command to view all the available fixtures. If you want to view the fixtures starting with "at the same time, you need to add the - v option:
λ pipenv run pytest -q -v --fixtures ============================= test session starts ============================== platform win32 -- Python 3.7.3, pytest-5.1.3, py-1.8.0, pluggy-0.13.0 rootdir: D:\Personal Files\Projects\pytest-chinese-doc collected 5 items cache Return a cache object that can persist state between testing sessions. cache.get(key, default) cache.set(key, value) Keys must be a ``/`` separated value, where the first part is usually the name of your plugin or application to avoid clashes with other cache users. Values can be any object handled by the json stdlib module. capsys Enable text capturing of writes to ``sys.stdout`` and ``sys.stderr``. The captured output is made available via ``capsys.readouterr()`` method calls, which return a ``(out, err)`` namedtuple. ``out`` and ``err`` will be ``text`` objects. capsysbinary Enable bytes capturing of writes to ``sys.stdout`` and ``sys.stderr``. The captured output is made available via ``capsysbinary.readouterr()`` method calls, which return a ``(out, err)`` namedtuple. ``out`` and ``err`` will be ``bytes`` objects. capfd Enable text capturing of writes to file descriptors ``1`` and ``2``. The captured output is made available via ``capfd.readouterr()`` method calls, which return a ``(out, err)`` namedtuple. ``out`` and ``err`` will be ``text`` objects. capfdbinary Enable bytes capturing of writes to file descriptors ``1`` and ``2``. The captured output is made available via ``capfd.readouterr()`` method calls, which return a ``(out, err)`` namedtuple. ``out`` and ``err`` will be ``byte`` objects. doctest_namespace [session scope] Fixture that returns a :py:class:`dict` that will be injected into the namespace of doctests. pytestconfig [session scope] Session-scoped fixture that returns the :class:`_pytest.config.Config` object. Example:: def test_foo(pytestconfig): if pytestconfig.getoption("verbose") > 0: ... record_property Add an extra properties the calling test. User properties become part of the test report and are available to the configured reporters, like JUnit XML. The fixture is callable with ``(name, value)``, with value being automatically xml-encoded. Example:: def test_function(record_property): record_property("example_key", 1) record_xml_attribute Add extra xml attributes to the tag for the calling test. The fixture is callable with ``(name, value)``, with value being automatically xml-encoded record_testsuite_property [session scope] Records a new ``<property>`` tag as child of the root ``<testsuite>``. This is suitable to writing global information regarding the entire test suite, and is compatible with ``xunit2`` JUnit family. This is a ``session``-scoped fixture which is called with ``(name, value)``. Example: .. code-block:: python def test_foo(record_testsuite_property): record_testsuite_property("ARCH", "PPC") record_testsuite_property("STORAGE_TYPE", "CEPH") ``name`` must be a string, ``value`` will be converted to a string and properly xml-escaped. caplog Access and control log capturing. Captured logs are available through the following properties/methods:: * caplog.text -> string containing formatted log output * caplog.records -> list of logging.LogRecord instances * caplog.record_tuples -> list of (logger_name, level, message) tuples * caplog.clear() -> clear captured records and formatted log output string monkeypatch The returned ``monkeypatch`` fixture provides these helper methods to modify objects, dictionaries or os.environ:: monkeypatch.setattr(obj, name, value, raising=True) monkeypatch.delattr(obj, name, raising=True) monkeypatch.setitem(mapping, name, value) monkeypatch.delitem(obj, name, raising=True) monkeypatch.setenv(name, value, prepend=False) monkeypatch.delenv(name, raising=True) monkeypatch.syspath_prepend(path) monkeypatch.chdir(path) All modifications will be undone after the requesting test function or fixture has finished. The ``raising`` parameter determines if a KeyError or AttributeError will be raised if the set/deletion operation has no target. recwarn Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions. See http://docs.python.org/library/warnings.html for information on warning categories. tmpdir_factory [session scope] Return a :class:`_pytest.tmpdir.TempdirFactory` instance for the test session. tmp_path_factory [session scope] Return a :class:`_pytest.tmpdir.TempPathFactory` instance for the test session. tmpdir Return a temporary directory path object which is unique to each test function invocation, created as a sub directory of the base temporary directory. The returned object is a `py.path.local`_ path object. .. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html tmp_path Return a temporary directory path object which is unique to each test function invocation, created as a sub directory of the base temporary directory. The returned object is a :class:`pathlib.Path` object. .. note:: in python < 3.6 this is a pathlib2.Path ============================ no tests ran in 0.10s =============================
GitHub warehouse address: https://github.com/luizyao/pytest-chinese-doc