2021-03-12 04:30:47 +08:00
.. _get-started:
2021-03-11 02:27:30 +08:00
Get Started
2010-10-14 07:25:09 +08:00
===================================
2010-10-14 01:30:00 +08:00
2010-11-25 19:11:10 +08:00
.. _`getstarted`:
2018-01-16 05:27:10 +08:00
.. _`installation`:
2010-11-25 19:11:10 +08:00
2018-01-16 04:28:21 +08:00
Install `` pytest ``
2010-10-25 03:55:27 +08:00
----------------------------------------
2010-10-14 01:30:00 +08:00
2023-07-01 06:19:19 +08:00
`` pytest `` requires: Python 3.8+ or PyPy3.
2021-03-11 02:27:30 +08:00
2019-02-15 21:10:37 +08:00
1. Run the following command in your command line:
.. code-block :: bash
2010-10-14 07:25:09 +08:00
2016-08-23 10:35:41 +08:00
pip install -U pytest
2010-10-14 07:25:09 +08:00
2019-02-15 21:10:37 +08:00
2. Check that you installed the correct version:
.. code-block :: bash
2010-10-14 07:25:09 +08:00
2016-06-21 22:16:57 +08:00
$ pytest --version
2024-03-09 19:51:20 +08:00
pytest 8.1.1
2010-10-14 01:30:00 +08:00
2018-01-16 05:27:10 +08:00
.. _`simpletest`:
2010-11-25 19:11:10 +08:00
2018-01-16 04:28:21 +08:00
Create your first test
2010-10-25 03:55:27 +08:00
----------------------------------------------------------
2010-10-14 01:30:00 +08:00
2021-03-11 02:27:30 +08:00
Create a new file called `` test_sample.py `` , containing a function, and a test:
2010-10-14 01:30:00 +08:00
2019-08-07 04:25:54 +08:00
.. code-block :: python
2010-10-14 01:30:00 +08:00
# content of test_sample.py
def func(x):
return x + 1
2010-11-06 06:37:25 +08:00
2019-08-07 04:34:58 +08:00
2010-10-14 01:30:00 +08:00
def test_answer():
assert func(3) == 5
2021-03-11 02:27:30 +08:00
The test
2018-11-24 13:41:22 +08:00
.. code-block :: pytest
2010-10-14 01:30:00 +08:00
2016-06-21 22:16:57 +08:00
$ pytest
2017-11-23 23:33:41 +08:00
=========================== test session starts ============================
2024-01-02 16:58:20 +08:00
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
2021-10-04 14:56:26 +08:00
rootdir: /home/sweet/project
2017-07-04 07:29:13 +08:00
collected 1 item
2018-05-18 16:19:46 +08:00
2017-11-23 23:33:41 +08:00
test_sample.py F [100%]
2018-05-18 16:19:46 +08:00
2017-11-23 23:33:41 +08:00
================================= FAILURES =================================
_______________________________ test_answer ________________________________
2018-05-18 16:19:46 +08:00
2010-10-14 01:30:00 +08:00
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
2018-05-18 16:19:46 +08:00
2019-08-16 08:00:09 +08:00
test_sample.py:6: AssertionError
2020-03-11 22:23:25 +08:00
========================= short test summary info ==========================
FAILED test_sample.py::test_answer - assert 4 == 5
2019-08-30 23:43:47 +08:00
============================ 1 failed in 0.12s =============================
2010-10-14 01:30:00 +08:00
2020-05-19 01:51:22 +08:00
The `` [100%] `` refers to the overall progress of running all test cases. After it finishes, pytest then shows a failure report because `` func(3) `` does not return `` 5 `` .
2010-10-14 01:30:00 +08:00
2010-11-02 07:53:53 +08:00
.. note ::
2010-10-14 01:30:00 +08:00
2021-08-26 22:05:03 +08:00
You can use the `` assert `` statement to verify test expectations. pytest’ s :ref: `Advanced assertion introspection <python:assert>` will intelligently report intermediate values of the assert expression so you can avoid the many names :ref: `of JUnit legacy methods <testcase-objects>` .
2010-10-14 01:30:00 +08:00
2018-01-16 04:28:21 +08:00
Run multiple tests
2015-09-26 12:41:17 +08:00
----------------------------------------------------------
2018-01-16 04:28:21 +08:00
`` pytest `` will run all files of the form test_*.py or \* _test.py in the current directory and its subdirectories. More generally, it follows :ref: `standard test discovery rules <test discovery>` .
2015-09-26 12:41:17 +08:00
2018-01-16 04:28:21 +08:00
Assert that a certain exception is raised
2010-10-25 03:55:27 +08:00
--------------------------------------------------------------
2019-08-07 07:20:06 +08:00
Use the :ref: `raises <assertraises>` helper to assert that some code raises an exception:
2010-10-25 03:55:27 +08:00
2019-08-07 04:25:54 +08:00
.. code-block :: python
2010-10-25 03:55:27 +08:00
# content of test_sysexit.py
2010-11-18 05:12:16 +08:00
import pytest
2019-08-07 04:34:58 +08:00
2010-10-25 03:55:27 +08:00
def f():
raise SystemExit(1)
2019-08-07 04:34:58 +08:00
2010-10-25 03:55:27 +08:00
def test_mytest():
2010-11-18 05:12:16 +08:00
with pytest.raises(SystemExit):
2010-10-25 03:55:27 +08:00
f()
2023-09-18 05:26:58 +08:00
You can also use the context provided by :ref: `raises <assertraises>` to
2024-01-02 16:58:20 +08:00
assert that an expected exception is part of a raised :class: `ExceptionGroup` :
2023-09-18 05:26:58 +08:00
.. code-block :: python
# content of test_exceptiongroup.py
import pytest
def f():
raise ExceptionGroup(
"Group message",
[
RuntimeError(),
],
)
def test_exception_in_group():
with pytest.raises(ExceptionGroup) as excinfo:
f()
assert excinfo.group_contains(RuntimeError)
assert not excinfo.group_contains(TypeError)
2010-10-25 03:55:27 +08:00
2018-11-24 13:41:22 +08:00
Execute the test function with “quiet” reporting mode:
.. code-block :: pytest
2010-11-02 07:53:53 +08:00
2016-06-21 22:16:57 +08:00
$ pytest -q test_sysexit.py
2017-11-23 23:33:41 +08:00
. [100%]
2019-09-18 21:11:59 +08:00
1 passed in 0.12s
2010-11-02 07:53:53 +08:00
2020-07-20 03:29:19 +08:00
.. note ::
The `` -q/--quiet `` flag keeps the output brief in this and following examples.
2018-01-16 04:28:21 +08:00
Group multiple tests in a class
2010-11-02 07:53:53 +08:00
--------------------------------------------------------------
2020-07-08 05:48:02 +08:00
.. regendoc:wipe
2019-08-07 07:20:06 +08:00
Once you develop multiple tests, you may want to group them into a class. pytest makes it easy to create a class containing more than one test:
2010-11-02 07:53:53 +08:00
2019-08-07 04:25:54 +08:00
.. code-block :: python
2010-11-02 07:53:53 +08:00
# content of test_class.py
2017-02-17 02:41:51 +08:00
class TestClass:
2010-11-02 07:53:53 +08:00
def test_one(self):
x = "this"
assert "h" in x
2010-10-25 03:55:27 +08:00
2010-11-02 07:53:53 +08:00
def test_two(self):
x = "hello"
assert hasattr(x, "check")
2020-01-27 17:50:05 +08:00
`` pytest `` discovers all tests following its :ref: `Conventions for Python test discovery <test discovery>` , so it finds both `` test_ `` prefixed functions. There is no need to subclass anything, but make sure to prefix your class with `` Test `` otherwise the class will be skipped. We can simply run the module by passing its filename:
2018-11-24 13:41:22 +08:00
.. code-block :: pytest
2010-11-02 07:53:53 +08:00
2016-06-21 22:16:57 +08:00
$ pytest -q test_class.py
2017-11-23 23:33:41 +08:00
.F [100%]
================================= FAILURES =================================
____________________________ TestClass.test_two ____________________________
2018-05-18 16:19:46 +08:00
2021-10-04 14:56:26 +08:00
self = <test_class.TestClass object at 0xdeadbeef0001>
2018-05-18 16:19:46 +08:00
2010-11-02 07:53:53 +08:00
def test_two(self):
x = "hello"
2019-08-16 08:00:09 +08:00
> assert hasattr(x, "check")
2017-03-14 06:41:20 +08:00
E AssertionError: assert False
2016-08-02 02:46:34 +08:00
E + where False = hasattr('hello', 'check')
2018-05-18 16:19:46 +08:00
2010-11-02 07:53:53 +08:00
test_class.py:8: AssertionError
2020-03-11 22:23:25 +08:00
========================= short test summary info ==========================
FAILED test_class.py::TestClass::test_two - AssertionError: assert False
2019-09-18 21:11:59 +08:00
1 failed, 1 passed in 0.12s
2010-10-14 07:25:09 +08:00
2018-01-16 04:28:21 +08:00
The first test passed and the second failed. You can easily see the intermediate values in the assertion to help you understand the reason for the failure.
2010-11-06 06:37:25 +08:00
2020-05-24 18:43:29 +08:00
Grouping tests in classes can be beneficial for the following reasons:
2020-05-24 18:34:54 +08:00
2020-05-24 18:43:29 +08:00
* Test organization
2020-05-24 18:34:54 +08:00
* Sharing fixtures for tests only in that particular class
* Applying marks at the class level and having them implicitly apply to all tests
2020-05-24 23:33:17 +08:00
Something to be aware of when grouping tests inside classes is that each test has a unique instance of the class.
2020-05-24 18:34:54 +08:00
Having each test share the same class instance would be very detrimental to test isolation and would promote poor test practices.
This is outlined below:
2020-07-08 05:48:02 +08:00
.. regendoc:wipe
2020-05-24 18:34:54 +08:00
.. code-block :: python
2020-07-08 05:48:02 +08:00
# content of test_class_demo.py
2020-05-24 18:34:54 +08:00
class TestClassDemoInstance:
2021-05-27 00:06:47 +08:00
value = 0
2020-05-24 18:34:54 +08:00
def test_one(self):
2021-05-27 00:06:47 +08:00
self.value = 1
assert self.value == 1
2020-05-24 18:34:54 +08:00
def test_two(self):
2021-05-27 00:06:47 +08:00
assert self.value == 1
2020-05-24 18:34:54 +08:00
.. code-block :: pytest
$ pytest -k TestClassDemoInstance -q
2021-05-27 00:06:47 +08:00
.F [100%]
2020-07-09 05:51:01 +08:00
================================= FAILURES =================================
______________________ TestClassDemoInstance.test_two ______________________
2020-05-24 18:34:54 +08:00
2021-10-04 14:56:26 +08:00
self = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef0002>
2020-05-24 18:34:54 +08:00
2020-07-09 05:51:01 +08:00
def test_two(self):
2021-05-27 00:06:47 +08:00
> assert self.value == 1
E assert 0 == 1
2021-10-04 14:56:26 +08:00
E + where 0 = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef0002>.value
2020-05-24 18:34:54 +08:00
2021-05-27 00:06:47 +08:00
test_class_demo.py:9: AssertionError
2020-07-09 05:51:01 +08:00
========================= short test summary info ==========================
2021-05-27 00:06:47 +08:00
FAILED test_class_demo.py::TestClassDemoInstance::test_two - assert 0 == 1
2021-10-04 14:56:26 +08:00
1 failed, 1 passed in 0.12s
2020-05-24 18:34:54 +08:00
2021-01-25 23:02:59 +08:00
Note that attributes added at class level are *class attributes* , so they will be shared between tests.
2018-01-16 04:28:21 +08:00
Request a unique temporary directory for functional tests
2010-11-06 06:37:25 +08:00
--------------------------------------------------------------
2021-09-27 06:42:37 +08:00
`` pytest `` provides :std:doc: `Builtin fixtures/function arguments <builtin>` to request arbitrary resources, like a unique temporary directory:
2010-11-06 06:37:25 +08:00
2019-08-07 04:25:54 +08:00
.. code-block :: python
2021-03-14 03:22:54 +08:00
# content of test_tmp_path.py
def test_needsfiles(tmp_path):
print(tmp_path)
2010-11-06 06:37:25 +08:00
assert 0
2021-03-14 03:22:54 +08:00
List the name `` tmp_path `` in the test function signature and `` pytest `` will lookup and call a fixture factory to create the resource before performing the test function call. Before the test runs, `` pytest `` creates a unique-per-test-invocation temporary directory:
2018-11-24 13:41:22 +08:00
.. code-block :: pytest
2010-11-06 06:37:25 +08:00
2021-03-14 03:22:54 +08:00
$ pytest -q test_tmp_path.py
2017-11-23 23:33:41 +08:00
F [100%]
================================= FAILURES =================================
_____________________________ test_needsfiles ______________________________
2018-05-18 16:19:46 +08:00
2021-10-04 14:56:26 +08:00
tmp_path = PosixPath('PYTEST_TMPDIR/test_needsfiles0')
2018-05-18 16:19:46 +08:00
2021-03-14 03:22:54 +08:00
def test_needsfiles(tmp_path):
print(tmp_path)
2014-09-05 19:55:00 +08:00
> assert 0
E assert 0
2018-05-18 16:19:46 +08:00
2021-10-04 14:56:26 +08:00
test_tmp_path.py:3: AssertionError
2015-09-22 20:02:11 +08:00
--------------------------- Captured stdout call ---------------------------
PYTEST_TMPDIR/test_needsfiles0
2020-03-11 22:23:25 +08:00
========================= short test summary info ==========================
2021-03-14 03:22:54 +08:00
FAILED test_tmp_path.py::test_needsfiles - assert 0
2019-09-18 21:11:59 +08:00
1 failed in 0.12s
2010-11-06 06:37:25 +08:00
2021-07-14 23:53:27 +08:00
More info on temporary directory handling is available at :ref: `Temporary directories and files <tmp_path handling>` .
2010-11-06 06:37:25 +08:00
2019-02-15 21:10:37 +08:00
Find out what kind of builtin :ref: `pytest fixtures <fixtures>` exist with the command:
.. code-block :: bash
2010-11-06 06:37:25 +08:00
2016-06-21 22:16:57 +08:00
pytest --fixtures # shows builtin and custom fixtures
2010-11-06 06:37:25 +08:00
2018-04-14 16:56:13 +08:00
Note that this command omits fixtures with leading `` _ `` unless the `` -v `` option is added.
2018-01-16 04:28:21 +08:00
Continue reading
2010-10-14 07:25:09 +08:00
-------------------------------------
2018-01-16 04:28:21 +08:00
Check out additional pytest resources to help you customize tests for your unique workflow:
2010-10-14 07:25:09 +08:00
2021-03-22 07:04:12 +08:00
* ":ref: `usage` " for command line invocation examples
2018-01-16 04:28:21 +08:00
* ":ref: `existingtestsuite` " for working with pre-existing tests
2018-02-27 07:27:15 +08:00
* ":ref: `mark` " for information on the `` pytest.mark `` mechanism
2018-01-16 04:28:21 +08:00
* ":ref: `fixtures` " for providing a functional baseline to your tests
* ":ref: `plugins` " for managing and writing plugins
2018-02-27 07:27:15 +08:00
* ":ref: `goodpractices` " for virtualenv and test layouts