Jump to content

Pytest: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Xyb (talk | contribs)
Rescuing 13 sources and tagging 0 as dead.) #IABot (v2.0.9.5
 
(5 intermediate revisions by 5 users not shown)
Line 18: Line 18:
| released = <!-- {{Start date and age|YYYY|MM|DD|df=yes/no}} -->
| released = <!-- {{Start date and age|YYYY|MM|DD|df=yes/no}} -->
| discontinued =
| discontinued =
| latest release version = 7.3.1 <ref name="release">{{cite web|url=https://pypi.org/project/pytest/#history}|title="pytest 7.3.1"|website=pypi.org}}</ref>
| latest release version = {{wikidata|property|preferred|references|edit|P348|P548=Q2804309}}
| latest release date = 2023-04-14 <ref name="release"/>
| latest release date = {{Start date and age|{{wikidata|qualifier|preferred|single|P348|P548=Q2804309|P577}}}}
| latest preview version =
| latest preview version =
| latest preview date = <!-- {{Start date and age|YYYY|MM|DD|df=yes/no}} -->
| latest preview date = <!-- {{Start date and age|YYYY|MM|DD|df=yes/no}} -->
Line 40: Line 40:
==History==
==History==


Pytest was developed as part of an effort by [[Python Package Index|third-party packages]] to address [[Python (programming language)#Libraries|Python's built-in module]] unittest's shortcomings. It originated as part of PyPy, an alternative implementation of Python to the standard [[CPython]]. Since its creation in early 2003, PyPy has had a heavy emphasis on [[Software testing|testing]]. PyPy had unit tests for newly written code, regression tests for bugs, and integration tests using CPython's test suite.<ref name="PyPy">{{cite web |last1=Bolz-Tereick |first1=Carl Friedrich |title=PyPy Status Blog |url=https://morepypy.blogspot.com/2018/09/the-first-15-years-of-pypy.html#continuous-integration |website=PyPy |date=9 September 2018 |access-date=12 May 2022}}</ref>
Pytest was developed as part of an effort by [[Python Package Index|third-party packages]] to address [[Python (programming language)#Libraries|Python's built-in module]] unittest's shortcomings. It originated as part of PyPy, an alternative implementation of Python to the standard [[CPython]]. Since its creation in early 2003, PyPy has had a heavy emphasis on [[Software testing|testing]]. PyPy had unit tests for newly written code, regression tests for bugs, and integration tests using CPython's test suite.<ref name="PyPy">{{cite web |last1=Bolz-Tereick |first1=Carl Friedrich |title=PyPy Status Blog |url=https://morepypy.blogspot.com/2018/09/the-first-15-years-of-pypy.html#continuous-integration |website=PyPy |date=9 September 2018 |access-date=12 May 2022 |archive-date=6 July 2022 |archive-url=https://web.archive.org/web/20220706195902/https://morepypy.blogspot.com/2018/09/the-first-15-years-of-pypy.html#continuous-integration |url-status=live }}</ref>


In mid 2004, a testing framework called utest emerged and contributors to PyPy began converting existing [[test case]]s to utest. Meanwhile, at EuroPython 2004 a complementary [[standard library]] for testing, named std, was invented. This package laid out the principles, such as assert rewriting, of what would later become pytest. In late 2004, the std project was renamed to py, std.utest became py.test, and the py [[Library (computing)|library]] was separated from PyPy. In November 2010, pytest 2.0.0 was released as a package separate from py. It was still called py.test until August 2016, but following the release of pytest 3.0.0 the recommended [[Command-line interface|command line]] [[entry point]] became pytest.<ref name="pytest-history">{{cite web |title=History |url=https://docs.pytest.org/en/latest/history.html |website=pytest |access-date=13 April 2022}}</ref>
In mid 2004, a testing framework called utest emerged and contributors to PyPy began converting existing [[test case]]s to utest. Meanwhile, at EuroPython 2004 a complementary [[standard library]] for testing, named std, was invented. This package laid out the principles, such as assert rewriting, of what would later become pytest. In late 2004, the std project was renamed to py, std.utest became py.test, and the py [[Library (computing)|library]] was separated from PyPy. In November 2010, pytest 2.0.0 was released as a package separate from py. It was still called py.test until August 2016, but following the release of pytest 3.0.0 the recommended [[Command-line interface|command line]] [[entry point]] became pytest.<ref name="pytest-history">{{cite web |title=History |url=https://docs.pytest.org/en/latest/history.html |website=pytest |access-date=13 April 2022 |archive-date=16 May 2022 |archive-url=https://web.archive.org/web/20220516211537/https://docs.pytest.org/en/latest/history.html |url-status=live }}</ref>


Pytest has been classified by developer security platform Snyk as one of the key ecosystem projects in Python due to its popularity. Some well-known projects who switched to pytest from unittest and nose (another testing package) include those of [[Mozilla]] and [[Dropbox]].<ref>{{cite web |title=Project examples |url=https://docs.pytest.org/en/6.2.x/projects.html |website=Pytest |access-date=1 February 2022}}</ref><ref>{{cite web |last1=Koorapati |first1=Nipunn |title=Open Sourcing Pytest Tools |url=https://dropbox.tech/application/open-sourcing-pytest-tools |website=[[Dropbox]] |access-date=1 February 2022}}</ref><ref name="Oliveira">{{cite book |last1=Oliveira |first1=Bruno |title=pytest Quick Start Guide |date=August 2018 |publisher=[[Packt Publishing]] |isbn=978-1-78934-756-2 |url=https://www.packtpub.com/product/pytest-quick-start-guide/9781789347562 |access-date=1 February 2022}}</ref><ref name="Snyk">{{cite web |title=pytest |url=https://snyk.io/advisor/python/pytest |website=Snyk |access-date=12 May 2022}}</ref>
Pytest has been classified by developer security platform Snyk as one of the key ecosystem projects in Python due to its popularity. Some well-known projects who switched to pytest from unittest and nose (another testing package) include those of [[Mozilla]] and [[Dropbox]].<ref>{{cite web |title=Project examples |url=https://docs.pytest.org/en/6.2.x/projects.html |website=Pytest |access-date=1 February 2022 |archive-date=1 February 2022 |archive-url=https://web.archive.org/web/20220201223344/https://docs.pytest.org/en/6.2.x/projects.html |url-status=live }}</ref><ref>{{cite web |last1=Koorapati |first1=Nipunn |title=Open Sourcing Pytest Tools |url=https://dropbox.tech/application/open-sourcing-pytest-tools |website=[[Dropbox]] |access-date=1 February 2022 |archive-date=11 June 2024 |archive-url=https://web.archive.org/web/20240611042915/https://dropbox.tech/application/open-sourcing-pytest-tools |url-status=live }}</ref><ref name="Oliveira">{{cite book |last1=Oliveira |first1=Bruno |title=pytest Quick Start Guide |date=August 2018 |publisher=[[Packt Publishing]] |isbn=978-1-78934-756-2 |url=https://www.packtpub.com/product/pytest-quick-start-guide/9781789347562 |access-date=1 February 2022 |archive-date=1 February 2022 |archive-url=https://web.archive.org/web/20220201231057/https://www.packtpub.com/product/pytest-quick-start-guide/9781789347562 |url-status=live }}</ref><ref name="Snyk">{{cite web |title=pytest |url=https://snyk.io/advisor/python/pytest |website=Snyk |access-date=12 May 2022 |archive-date=27 June 2022 |archive-url=https://web.archive.org/web/20220627024337/https://snyk.io/advisor/python/pytest |url-status=live }}</ref>


==Features==
==Features==
===Parametrized testing===
===Parametrized testing===
It is a common pattern in software testing to send values through test [[Subroutine|functions]] and check for correct output. In many cases, in order to thoroughly [[functional testing|test functionalities]], one needs to test multiple sets of input/output, and writing such cases separately would cause [[duplicate code]] as most of the actions would remain the same, only differing in input/output values. Pytest's parametrized testing feature eliminates such duplicate code by combining different iterations into one test case, then running these iterations and displaying each test's result separately.<ref name="okken">{{cite book |last1=Okken |first1=Brian |title=Python Testing with Pytest |date=September 2017 |publisher=The Pragmatic Bookshelf |isbn=9781680502404 |edition=1st |url=https://pragprog.com/titles/bopytest/python-testing-with-pytest/ |access-date=22 January 2022}}</ref>
It is a common pattern in software testing to send values through test [[Subroutine|functions]] and check for correct output. In many cases, in order to thoroughly [[functional testing|test functionalities]], one needs to test multiple sets of input/output, and writing such cases separately would cause [[duplicate code]] as most of the actions would remain the same, only differing in input/output values. Pytest's parametrized testing feature eliminates such duplicate code by combining different iterations into one test case, then running these iterations and displaying each test's result separately.<ref name="okken">{{cite book |last1=Okken |first1=Brian |title=Python Testing with Pytest |date=September 2017 |publisher=The Pragmatic Bookshelf |isbn=9781680502404 |edition=1st |url=https://pragprog.com/titles/bopytest/python-testing-with-pytest/ |access-date=22 January 2022 |archive-date=20 January 2022 |archive-url=https://web.archive.org/web/20220120135726/https://pragprog.com/titles/bopytest/python-testing-with-pytest/ |url-status=live }}</ref>


Parametrized tests in pytest are marked by the {{code|@pytest.mark.parametrize(argnames, argvalues)}} [[Python syntax and semantics#Decorators|decorator]], where the first [[Parameter (computer programming)|parameter]], {{code| argnames }}, is a string of comma-separated names, and {{code|argvalues}} is a list of values to pass into {{code| argnames }}. When there are multiple names in {{code| argnames }}, {{code|argvalues}} would be a list of tuples where values in each tuple corresponds to the names in {{code|argnames}} by index. The names in {{code|argnames}} are then passed into the test function marked by the decorator as parameters. When pytest runs such decorated tests, each pair of {{code| argnames }} and {{code|argvalues}} would constitute a separate run with its own test output and unique identifier. The identifier can then be used to run individual data pairs.{{r|okken|p=52–58}}<ref name="pytest-docs-param">{{cite web |title=Parametrizing fixtures and test functions |url=https://docs.pytest.org/en/6.2.x/parametrize.html |website=pytest.org |access-date=24 May 2022}}</ref>
Parametrized tests in pytest are marked by the {{code|@pytest.mark.parametrize(argnames, argvalues)}} [[Python syntax and semantics#Decorators|decorator]], where the first [[Parameter (computer programming)|parameter]], {{code| argnames }}, is a string of comma-separated names, and {{code|argvalues}} is a list of values to pass into {{code| argnames }}. When there are multiple names in {{code| argnames }}, {{code|argvalues}} would be a list of tuples where values in each tuple corresponds to the names in {{code|argnames}} by index. The names in {{code|argnames}} are then passed into the test function marked by the decorator as parameters. When pytest runs such decorated tests, each pair of {{code| argnames }} and {{code|argvalues}} would constitute a separate run with its own test output and unique identifier. The identifier can then be used to run individual data pairs.{{r|okken|p=52–58}}<ref name="pytest-docs-param">{{cite web |title=Parametrizing fixtures and test functions |url=https://docs.pytest.org/en/6.2.x/parametrize.html |website=pytest.org |access-date=24 May 2022 |archive-date=4 June 2022 |archive-url=https://web.archive.org/web/20220604202736/https://docs.pytest.org/en/6.2.x/parametrize.html |url-status=live }}</ref>


===Assert rewriting===
===Assert rewriting===
Line 65: Line 65:
| {{code|assertEqual(x, y)}}
| {{code|assertEqual(x, y)}}
|-
|-
| <syntaxhighlight lang="python" inline>assert x >= y</syntaxhighlight>
| <syntaxhighlight lang="python" inline>assert x <= y</syntaxhighlight>
| {{code|assertLessEqual(x, y)}}
| {{code|assertLessEqual(x, y)}}
|}
|}
Line 72: Line 72:


=== Pytest fixtures ===
=== Pytest fixtures ===
Pytest's tests verify that computer code performs as expected<ref name="Viafore">{{cite book |last1=Viafore |first1=Patrick |title=Robust Python |date=12 July 2021 |publisher=O'Reilly Media, Inc. |isbn=978-1-0981-0061-2 |url=https://books.google.com/books?id=mO43EAAAQBAJ&pg=PT313 |access-date=3 July 2022 |language=en |quote="Tests verify that what you build is performing as you expect."}}</ref> using tests that are structured in an arrange, act and assert sequence known as AAA.<ref name="Khorikov"/> Its [[Test fixture|fixtures]] provide the context for tests. They can be used to put a system into a known [[State (computer science)|state]] and to pass data into test functions. Fixtures practically constitute the ''arrange'' phase in the anatomy of a test (AAA, short for ''arrange'', ''act'', ''assert'').<ref name="Khorikov">{{cite book |last1=Khorikov |first1=Vladamir |title=Unit Testing Principles, Practices, and Patterns |date=January 2020 |publisher=Published by Manning Publications |isbn=9781617296277 |url=https://www.oreilly.com/library/view/unit-testing-principles/9781617296277/ |access-date=4 June 2022}}</ref><ref name="Viafore"/> Pytest fixtures can run before test cases as setup or after test cases for clean up, but are different from unittest and nose (another third-party Python testing framework)'s [[Test fixture#Setup|setups]] and [[Test fixture#Examples|teardowns]]. Functions declared as pytest fixtures are marked by the {{code|@pytest.fixture}} [[Python syntax and semantics#Decorators|decorator]], whose names can then be passed into test functions as parameters.<ref>{{cite web |title=About fixtures |url=https://docs.pytest.org/en/latest/explanation/fixtures.html |website=Pytest |access-date=7 February 2022}}</ref> When pytest finds the fixtures' names in test functions' parameters, it first searches in the same module for such fixtures, and if not found, it searches for such fixtures in the conftest.py file.{{r|okken|p=61}}
Pytest's tests verify that computer code performs as expected<ref name="Viafore">{{cite book |last1=Viafore |first1=Patrick |title=Robust Python |date=12 July 2021 |publisher=O'Reilly Media, Inc. |isbn=978-1-0981-0061-2 |url=https://books.google.com/books?id=mO43EAAAQBAJ&pg=PT313 |access-date=3 July 2022 |language=en |quote="Tests verify that what you build is performing as you expect." |archive-date=3 July 2022 |archive-url=https://web.archive.org/web/20220703205741/https://books.google.com/books?id=mO43EAAAQBAJ&pg=PT313 |url-status=live }}</ref> using tests that are structured in an arrange, act and assert sequence known as AAA.<ref name="Khorikov"/> Its [[Test fixture|fixtures]] provide the context for tests. They can be used to put a system into a known [[State (computer science)|state]] and to pass data into test functions. Fixtures practically constitute the ''arrange'' phase in the anatomy of a test (AAA, short for ''arrange'', ''act'', ''assert'').<ref name="Khorikov">{{cite book |last1=Khorikov |first1=Vladimir |title=Unit Testing Principles, Practices, and Patterns |date=January 2020 |publisher=Published by Manning Publications |isbn=9781617296277 |url=https://www.oreilly.com/library/view/unit-testing-principles/9781617296277/ |access-date=4 June 2022 |archive-date=4 June 2022 |archive-url=https://web.archive.org/web/20220604130844/https://www.oreilly.com/library/view/unit-testing-principles/9781617296277/ |url-status=live }}</ref><ref name="Viafore"/> Pytest fixtures can run before test cases as setup or after test cases for clean up, but are different from unittest and nose (another third-party Python testing framework)'s [[Test fixture#Setup|setups]] and [[Test fixture#Examples|teardowns]]. Functions declared as pytest fixtures are marked by the {{code|@pytest.fixture}} [[Python syntax and semantics#Decorators|decorator]], whose names can then be passed into test functions as parameters.<ref>{{cite web |title=About fixtures |url=https://docs.pytest.org/en/latest/explanation/fixtures.html |website=Pytest |access-date=7 February 2022 |archive-date=7 February 2022 |archive-url=https://web.archive.org/web/20220207024326/https://docs.pytest.org/en/latest/explanation/fixtures.html |url-status=live }}</ref> When pytest finds the fixtures' names in test functions' parameters, it first searches in the same module for such fixtures, and if not found, it searches for such fixtures in the conftest.py file.{{r|okken|p=61}}


For example:
For example:
Line 93: Line 93:
====Fixture scopes====
====Fixture scopes====


In pytest, fixture scopes let the user define when a fixture should be called. There are four fixture scopes: [[Function object|function]] scope, [[Class (computer programming)|class]] scope, [[Modular programming|module]] scope, and session scope. Function-scoped fixtures are default for all pytest fixtures, which are called every time a function having the fixture as a parameter runs. The goal of specifying a broader fixture scope is to eliminate repeated fixture calls, which could slow down test execution. Class-scoped fixtures are called once per test class, regardless of the number of times they are called, and the same logic goes for all other scopes. When changing fixture scope, one need only add the scope parameter to fixture decorators, for example, {{code|2=python|1=@pytest.fixture(scope="class")}}.{{r|okken|p=72}}<ref name="Apress">{{cite book |last1=Ashwin |first1=Pajankar |title=Python Unit Test Automation: Practical Techniques for Python Developers and Testers |date=27 February 2017 |publisher=Apress |isbn=9781484226766 |url=https://www.oreilly.com/library/view/python-unit-test/9781484226766/ |access-date=7 March 2022}}</ref>
In pytest, fixture scopes let the user define when a fixture should be called. There are four fixture scopes: [[Function object|function]] scope, [[Class (computer programming)|class]] scope, [[Modular programming|module]] scope, and session scope. Function-scoped fixtures are default for all pytest fixtures, which are called every time a function having the fixture as a parameter runs. The goal of specifying a broader fixture scope is to eliminate repeated fixture calls, which could slow down test execution. Class-scoped fixtures are called once per test class, regardless of the number of times they are called, and the same logic goes for all other scopes. When changing fixture scope, one need only add the scope parameter to fixture decorators, for example, {{code|2=python|1=@pytest.fixture(scope="class")}}.{{r|okken|p=72}}<ref name="Apress">{{cite book |last1=Ashwin |first1=Pajankar |title=Python Unit Test Automation: Practical Techniques for Python Developers and Testers |date=27 February 2017 |publisher=Apress |isbn=9781484226766 |url=https://www.oreilly.com/library/view/python-unit-test/9781484226766/ |access-date=7 March 2022 |archive-date=7 March 2022 |archive-url=https://web.archive.org/web/20220307035055/https://www.oreilly.com/library/view/python-unit-test/9781484226766/ |url-status=live }}</ref>


===Test filtering===
===Test filtering===
Another feature of pytest is its ability to filter through tests, where only desired tests are selected to run, or behave in a certain way as desired by the developer. With the "k" [[Command-line interface#Command-line option|option]] (e.g. {{kbd|pytest -k some_name}}), pytest would only run tests whose names include {{code|some_name}}. The opposite is true, where one can run {{kbd|pytest -k "not some_name"}}, and pytest will run all tests whose names do not include {{code|some_name}}.<ref name="Molina">{{cite book |last1=Molina |first1=Alessandro |title=Crafting Test-Driven Software with Python |date=February 2021 |publisher=Publisher(s): Packt Publishing |isbn=9781838642655 |url=https://www.oreilly.com/library/view/crafting-test-driven-software/9781838642655/ |access-date=8 March 2022}}</ref>
Another feature of pytest is its ability to filter through tests, where only desired tests are selected to run, or behave in a certain way as desired by the developer. With the "k" [[Command-line interface#Command-line option|option]] (e.g. {{kbd|pytest -k some_name}}), pytest would only run tests whose names include {{code|some_name}}. The opposite is true, where one can run {{kbd|pytest -k "not some_name"}}, and pytest will run all tests whose names do not include {{code|some_name}}.<ref name="Molina">{{cite book |last1=Molina |first1=Alessandro |title=Crafting Test-Driven Software with Python |date=February 2021 |publisher=Publisher(s): Packt Publishing |isbn=9781838642655 |url=https://www.oreilly.com/library/view/crafting-test-driven-software/9781838642655/ |access-date=8 March 2022 |archive-date=8 March 2022 |archive-url=https://web.archive.org/web/20220308025240/https://www.oreilly.com/library/view/crafting-test-driven-software/9781838642655/ |url-status=live }}</ref>


Pytest's markers can, in addition to altering test behaviour, also filter tests. Pytest's markers are Python decorators starting with the {{code|2=python|@pytest.mark.<markername>}} syntax placed on top of test functions. With different arbitrarily named markers, running {{kbd|pytest -m <markername>}} on the command line will only run those tests decorated with such markers.{{r|okken|p=13}} All available markers can be listed by the {{kbd|pytest --markers}} along with their descriptions; custom markers can also be defined by users and registered in pytest.ini, in which case {{kbd|pytest --markers}} will also list those custom markers along with builtin markers.{{r|okken|p=147}}
Pytest's markers can, in addition to altering test behaviour, also filter tests. Pytest's markers are Python decorators starting with the {{code|2=python|@pytest.mark.<markername>}} syntax placed on top of test functions. With different arbitrarily named markers, running {{kbd|pytest -m <markername>}} on the command line will only run those tests decorated with such markers.{{r|okken|p=13}} All available markers can be listed by the {{kbd|pytest --markers}} along with their descriptions; custom markers can also be defined by users and registered in pytest.ini, in which case {{kbd|pytest --markers}} will also list those custom markers along with builtin markers.{{r|okken|p=147}}
Line 111: Line 111:


== External links ==
== External links ==
* {{Official website}}
* [https://pypi.python.org/pypi/pytest https://pypi.python.org/pypi/pytest]
* [https://pypi.org/project/pytest/ https://pypi.org/project/pytest/]
* [https://docs.pytest.org https://docs.pytest.org]
* [https://docs.pytest.org https://docs.pytest.org]


[[Category:Python (programming language) development tools]]
[[Category:Python (programming language) development tools]]
[[Category:Free software testing tools]]
[[Category:Free software testing tools]]
[[Category:Unit testing frameworks]]

Latest revision as of 04:29, 11 June 2024

Pytest
Original author(s)Krekel et al.
Stable release
8.3.3[1] Edit this on Wikidata / 10 September 2024; 3 months ago (10 September 2024)
Repository
Written inPython
PlatformmacOS, Windows, POSIX
TypeFramework for software testing
LicenseMIT License
Websitepytest.org Edit this on Wikidata

Pytest is a Python testing framework that originated from the PyPy project. It can be used to write various types of software tests, including unit tests, integration tests, end-to-end tests, and functional tests. Its features include parametrized testing, fixtures, and assert re-writing.

Pytest fixtures provide the contexts for tests by passing in parameter names in test cases; its parametrization eliminates duplicate code for testing multiple sets of input and output; and its rewritten assert statements provide detailed output for causes of failures.

History

[edit]

Pytest was developed as part of an effort by third-party packages to address Python's built-in module unittest's shortcomings. It originated as part of PyPy, an alternative implementation of Python to the standard CPython. Since its creation in early 2003, PyPy has had a heavy emphasis on testing. PyPy had unit tests for newly written code, regression tests for bugs, and integration tests using CPython's test suite.[2]

In mid 2004, a testing framework called utest emerged and contributors to PyPy began converting existing test cases to utest. Meanwhile, at EuroPython 2004 a complementary standard library for testing, named std, was invented. This package laid out the principles, such as assert rewriting, of what would later become pytest. In late 2004, the std project was renamed to py, std.utest became py.test, and the py library was separated from PyPy. In November 2010, pytest 2.0.0 was released as a package separate from py. It was still called py.test until August 2016, but following the release of pytest 3.0.0 the recommended command line entry point became pytest.[3]

Pytest has been classified by developer security platform Snyk as one of the key ecosystem projects in Python due to its popularity. Some well-known projects who switched to pytest from unittest and nose (another testing package) include those of Mozilla and Dropbox.[4][5][6][7]

Features

[edit]

Parametrized testing

[edit]

It is a common pattern in software testing to send values through test functions and check for correct output. In many cases, in order to thoroughly test functionalities, one needs to test multiple sets of input/output, and writing such cases separately would cause duplicate code as most of the actions would remain the same, only differing in input/output values. Pytest's parametrized testing feature eliminates such duplicate code by combining different iterations into one test case, then running these iterations and displaying each test's result separately.[8]

Parametrized tests in pytest are marked by the @pytest.mark.parametrize(argnames, argvalues) decorator, where the first parameter, argnames, is a string of comma-separated names, and argvalues is a list of values to pass into argnames. When there are multiple names in argnames, argvalues would be a list of tuples where values in each tuple corresponds to the names in argnames by index. The names in argnames are then passed into the test function marked by the decorator as parameters. When pytest runs such decorated tests, each pair of argnames and argvalues would constitute a separate run with its own test output and unique identifier. The identifier can then be used to run individual data pairs.[8]: 52–58 [9]

Assert rewriting

[edit]

When writing software tests, the assert statement is a primary means for communicating test failure, where expected values are compared to actual values.[8]: 32–34  While Python's built-in assert keyword would only raise AssertionError with no details in cases of failure, pytest rewrites Python's assert keyword and provides detailed output for the causes of failures, such as what expressions in the assert statement evaluate to. A comparison can be made with unittest (Python's built-in module for testing)'s assert statements:[8]: 32 

pytest unittest
assert x assertTrue(x)
assert x == y assertEqual(x, y)
assert x <= y assertLessEqual(x, y)

unittest adheres to a more verbose syntax because it is inspired by the Java programming language's JUnit, as are most unit testing libraries; pytest achieves the same while intercepting Python's built-in assert calls, making the approach more concise.[8]: 32 [6]

Pytest fixtures

[edit]

Pytest's tests verify that computer code performs as expected[10] using tests that are structured in an arrange, act and assert sequence known as AAA.[11] Its fixtures provide the context for tests. They can be used to put a system into a known state and to pass data into test functions. Fixtures practically constitute the arrange phase in the anatomy of a test (AAA, short for arrange, act, assert).[11][10] Pytest fixtures can run before test cases as setup or after test cases for clean up, but are different from unittest and nose (another third-party Python testing framework)'s setups and teardowns. Functions declared as pytest fixtures are marked by the @pytest.fixture decorator, whose names can then be passed into test functions as parameters.[12] When pytest finds the fixtures' names in test functions' parameters, it first searches in the same module for such fixtures, and if not found, it searches for such fixtures in the conftest.py file.[8]: 61 

For example:

import pytest

@pytest.fixture
def dataset():
    """Return some data to test functions"""
    return {'data1': 1, 'data2': 2}

def test_dataset(dataset):
    """test and confirm fixture value"""
    assert dataset == {'data1': 1, 'data2': 2}

In the above example, pytest fixture dataset returns a dictionary, which is then passed into test function test_dataset for assertion. In addition to fixture detection within the same file as test cases, pytest fixtures can also be placed in the conftest.py file in the tests directory. There can be multiple conftest.py files, each placed within a tests directory for fixtures to be detected for each subset of tests.[8]: 63 

Fixture scopes

[edit]

In pytest, fixture scopes let the user define when a fixture should be called. There are four fixture scopes: function scope, class scope, module scope, and session scope. Function-scoped fixtures are default for all pytest fixtures, which are called every time a function having the fixture as a parameter runs. The goal of specifying a broader fixture scope is to eliminate repeated fixture calls, which could slow down test execution. Class-scoped fixtures are called once per test class, regardless of the number of times they are called, and the same logic goes for all other scopes. When changing fixture scope, one need only add the scope parameter to fixture decorators, for example, @pytest.fixture(scope="class").[8]: 72 [13]

Test filtering

[edit]

Another feature of pytest is its ability to filter through tests, where only desired tests are selected to run, or behave in a certain way as desired by the developer. With the "k" option (e.g. pytest -k some_name), pytest would only run tests whose names include some_name. The opposite is true, where one can run pytest -k "not some_name", and pytest will run all tests whose names do not include some_name.[14]

Pytest's markers can, in addition to altering test behaviour, also filter tests. Pytest's markers are Python decorators starting with the @pytest.mark.<markername> syntax placed on top of test functions. With different arbitrarily named markers, running pytest -m <markername> on the command line will only run those tests decorated with such markers.[8]: 13  All available markers can be listed by the pytest --markers along with their descriptions; custom markers can also be defined by users and registered in pytest.ini, in which case pytest --markers will also list those custom markers along with builtin markers.[8]: 147 

See also

[edit]

References

[edit]
  1. ^ "Release 8.3.3". 10 September 2024. Retrieved 26 September 2024.
  2. ^ Bolz-Tereick, Carl Friedrich (9 September 2018). "PyPy Status Blog". PyPy. Archived from the original on 6 July 2022. Retrieved 12 May 2022.
  3. ^ "History". pytest. Archived from the original on 16 May 2022. Retrieved 13 April 2022.
  4. ^ "Project examples". Pytest. Archived from the original on 1 February 2022. Retrieved 1 February 2022.
  5. ^ Koorapati, Nipunn. "Open Sourcing Pytest Tools". Dropbox. Archived from the original on 11 June 2024. Retrieved 1 February 2022.
  6. ^ a b Oliveira, Bruno (August 2018). pytest Quick Start Guide. Packt Publishing. ISBN 978-1-78934-756-2. Archived from the original on 1 February 2022. Retrieved 1 February 2022.
  7. ^ "pytest". Snyk. Archived from the original on 27 June 2022. Retrieved 12 May 2022.
  8. ^ a b c d e f g h i j Okken, Brian (September 2017). Python Testing with Pytest (1st ed.). The Pragmatic Bookshelf. ISBN 9781680502404. Archived from the original on 20 January 2022. Retrieved 22 January 2022.
  9. ^ "Parametrizing fixtures and test functions". pytest.org. Archived from the original on 4 June 2022. Retrieved 24 May 2022.
  10. ^ a b Viafore, Patrick (12 July 2021). Robust Python. O'Reilly Media, Inc. ISBN 978-1-0981-0061-2. Archived from the original on 3 July 2022. Retrieved 3 July 2022. Tests verify that what you build is performing as you expect.
  11. ^ a b Khorikov, Vladimir (January 2020). Unit Testing Principles, Practices, and Patterns. Published by Manning Publications. ISBN 9781617296277. Archived from the original on 4 June 2022. Retrieved 4 June 2022.
  12. ^ "About fixtures". Pytest. Archived from the original on 7 February 2022. Retrieved 7 February 2022.
  13. ^ Ashwin, Pajankar (27 February 2017). Python Unit Test Automation: Practical Techniques for Python Developers and Testers. Apress. ISBN 9781484226766. Archived from the original on 7 March 2022. Retrieved 7 March 2022.
  14. ^ Molina, Alessandro (February 2021). Crafting Test-Driven Software with Python. Publisher(s): Packt Publishing. ISBN 9781838642655. Archived from the original on 8 March 2022. Retrieved 8 March 2022.
[edit]