test_ok2/doc/en/getting-started.rst

263 lines
9.4 KiB
ReStructuredText
Raw Normal View History

2010-11-02 07:53:53 +08:00
Installation and Getting Started
===================================
**Pythons**: Python 3.5, 3.6, 3.7, 3.8, 3.9, PyPy3
2011-07-09 18:02:22 +08:00
**Platforms**: Linux and Windows
2011-07-09 18:02:22 +08:00
**PyPI package name**: `pytest <https://pypi.org/project/pytest/>`_
2018-01-16 04:28:21 +08:00
**Documentation as PDF**: `download latest <https://media.readthedocs.org/pdf/pytest/latest/pytest.pdf>`_
``pytest`` is a framework that makes building simple and scalable tests easy. Tests are expressive and readable—no boilerplate code required. Get started in minutes with a small unit test or complex functional test for your application or library.
.. _`getstarted`:
.. _`installation`:
2018-01-16 04:28:21 +08:00
Install ``pytest``
----------------------------------------
1. Run the following command in your command line:
.. code-block:: bash
pip install -U pytest
2. Check that you installed the correct version:
.. code-block:: bash
$ pytest --version
2020-03-12 22:14:35 +08:00
This is pytest version 5.x.y, imported from $PYTHON_PREFIX/lib/python3.8/site-packages/pytest/__init__.py
.. _`simpletest`:
2018-01-16 04:28:21 +08:00
Create your first test
----------------------------------------------------------
Create a simple test function with just four lines of code:
2019-08-07 04:25:54 +08:00
.. code-block:: python
# 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
def test_answer():
assert func(3) == 5
2018-11-24 13:41:22 +08:00
Thats it. You can now execute the test function:
.. code-block:: pytest
$ pytest
=========================== test session starts ============================
2019-07-05 08:01:16 +08:00
platform linux -- Python 3.x.y, pytest-5.x.y, py-1.x.y, pluggy-0.x.y
2019-01-31 00:25:38 +08:00
cachedir: $PYTHON_PREFIX/.pytest_cache
2019-04-15 22:24:17 +08:00
rootdir: $REGENDOC_TMPDIR
2017-07-04 07:29:13 +08:00
collected 1 item
test_sample.py F [100%]
================================= FAILURES =================================
_______________________________ test_answer ________________________________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
2019-08-16 08:00:09 +08:00
test_sample.py:6: AssertionError
========================= 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 =============================
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-11-02 07:53:53 +08:00
.. note::
You can use the ``assert`` statement to verify test expectations. pytests `Advanced assertion introspection <http://docs.python.org/reference/simple_stmts.html#the-assert-statement>`_ will intelligently report intermediate values of the assert expression so you can avoid the many names `of JUnit legacy methods <http://docs.python.org/library/unittest.html#test-cases>`_.
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
--------------------------------------------------------------
Use the :ref:`raises <assertraises>` helper to assert that some code raises an exception:
2019-08-07 04:25:54 +08:00
.. code-block:: python
# content of test_sysexit.py
import pytest
2019-08-07 04:34:58 +08:00
def f():
raise SystemExit(1)
2019-08-07 04:34:58 +08:00
def test_mytest():
with pytest.raises(SystemExit):
f()
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
$ pytest -q test_sysexit.py
. [100%]
2019-09-18 21:11:59 +08:00
1 passed in 0.12s
2010-11-02 07:53:53 +08:00
2018-01-16 04:28:21 +08:00
Group multiple tests in a class
2010-11-02 07:53:53 +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
2019-08-07 04:33:21 +08:00
class TestClass:
2010-11-02 07:53:53 +08:00
def test_one(self):
x = "this"
2019-08-07 04:34:58 +08:00
assert "h" in x
2010-11-02 07:53:53 +08:00
def test_two(self):
x = "hello"
2019-08-07 04:34:58 +08:00
assert hasattr(x, "check")
2010-11-02 07:53:53 +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
$ pytest -q test_class.py
.F [100%]
================================= FAILURES =================================
____________________________ TestClass.test_two ____________________________
2015-09-22 22:52:35 +08:00
self = <test_class.TestClass object at 0xdeadbeef>
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')
2010-11-02 07:53:53 +08:00
test_class.py:8: AssertionError
========================= 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
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
Grouping tests in classes can be beneficial for the following reasons:
2020-05-24 18:34:54 +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:
.. code-block:: python
class TestClassDemoInstance:
def test_one(self):
assert 0
def test_two(self):
assert 0
.. code-block:: pytest
$ pytest -k TestClassDemoInstance -q
FF [100%]
================================== FAILURES ===================================
_______________________ TestClassDemoInstance.test_one ________________________
2020-05-24 18:34:54 +08:00
self = <test_example.TestClassDemoInstance object at 0x0000019BBB9EEDA0>
request = <FixtureRequest for <Function test_one>>
2020-05-24 18:34:54 +08:00
def test_one(self, request):
> assert 0
E assert 0
testing\test_example.py:4: AssertionError
_______________________ TestClassDemoInstance.test_two ________________________
2020-05-24 18:34:54 +08:00
self = <test_example.TestClassDemoInstance object at 0x0000019BBB9F3D68>
request = <FixtureRequest for <Function test_two>>
2020-05-24 18:34:54 +08:00
def test_two(self, request):
> assert 0
E assert 0
testing\test_example.py:7: AssertionError
=========================== short test summary info ===========================
2020-05-24 18:34:54 +08:00
FAILED testing/test_example.py::TestClassDemoInstance::test_one - assert 0
FAILED testing/test_example.py::TestClassDemoInstance::test_two - assert 0
2 failed in 0.11s
2020-05-24 18:34:54 +08:00
2018-01-16 04:28:21 +08:00
Request a unique temporary directory for functional tests
2010-11-06 06:37:25 +08:00
--------------------------------------------------------------
``pytest`` provides `Builtin fixtures/function arguments <https://docs.pytest.org/en/latest/builtin.html>`_ 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
2010-11-06 06:37:25 +08:00
# content of test_tmpdir.py
def test_needsfiles(tmpdir):
2018-11-22 16:15:14 +08:00
print(tmpdir)
2010-11-06 06:37:25 +08:00
assert 0
2018-11-24 13:41:22 +08:00
List the name ``tmpdir`` 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:
.. code-block:: pytest
2010-11-06 06:37:25 +08:00
$ pytest -q test_tmpdir.py
F [100%]
================================= FAILURES =================================
_____________________________ test_needsfiles ______________________________
tmpdir = local('PYTEST_TMPDIR/test_needsfiles0')
2014-09-05 19:55:00 +08:00
def test_needsfiles(tmpdir):
2018-11-22 16:15:14 +08:00
print(tmpdir)
2014-09-05 19:55:00 +08:00
> assert 0
E assert 0
2014-09-05 19:55:00 +08:00
test_tmpdir.py:3: AssertionError
--------------------------- Captured stdout call ---------------------------
PYTEST_TMPDIR/test_needsfiles0
========================= short test summary info ==========================
FAILED test_tmpdir.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
More info on tmpdir handling is available at :ref:`Temporary directories and files <tmpdir handling>`.
2010-11-06 06:37:25 +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
pytest --fixtures # shows builtin and custom fixtures
2010-11-06 06:37:25 +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
-------------------------------------
2018-01-16 04:28:21 +08:00
Check out additional pytest resources to help you customize tests for your unique workflow:
2018-01-16 04:28:21 +08:00
* ":ref:`cmdline`" for command line invocation examples
* ":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