test_ok2/doc/en/getting-started.rst

261 lines
10 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
2020-05-24 18:34:54 +08:00
Some reasons why grouping tests in a class can be useful is:
* Structural or organizational reasons
* Sharing fixtures for tests only in that particular class
* Applying marks at the class level and having them implicitly apply to all tests
Something to be aware of when grouping tests inside classes is that each test does not have the same instance of the class.
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 ____________________________________________________________________________________________________
self = <test_example.TestClassDemoInstance object at 0x000001F001A24EB8>, request = <FixtureRequest for <Function test_one>>
def test_one(self, request):
> assert 0
E assert 0
testing\test_example.py:4: AssertionError
___________________________________________________________________________________________________ TestClassDemoInstance.test_two ____________________________________________________________________________________________________
self = <test_example.TestClassDemoInstance object at 0x000001F001A54908>, request = <FixtureRequest for <Function test_two>>
def test_two(self, request):
> assert 0
E assert 0
testing\test_example.py:7: AssertionError
======================================================================================================= short test summary info =======================================================================================================
FAILED testing/test_example.py::TestClassDemoInstance::test_one - assert 0
FAILED testing/test_example.py::TestClassDemoInstance::test_two - assert 0
2 failed in 0.17s
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