Pytest Cheat Sheet #
Pytest is a powerful and easy-to-use testing framework for Python. This cheat sheet covers its essential features, commands, and best practices to streamline your testing workflow.
Getting Started #
Installation #
Install pytest using pip:
pip install pytestBasic Test File #
Save the following as test_sample.py:
def test_example():
assert 1 + 1 == 2Run tests:
pytestWriting Tests #
Test Naming Convention #
- Test files should start with
test_or end with_test. - Test functions should start with
test_.
Assertions #
Use Python’s assert statement for validations:
def test_math():
assert 2 * 2 == 4
assert "abc" in "abcdef"Markers #
Markers allow you to categorize tests:
import pytest
@pytest.mark.slow
def test_slow_operation():
import time
time.sleep(5)
assert TrueRun marked tests:
pytest -m slowFixtures #
Basic Fixture #
Fixtures set up resources needed for your tests:
import pytest
@pytest.fixture
def sample_data():
return [1, 2, 3]
def test_data_length(sample_data):
assert len(sample_data) == 3Fixture Scope #
Control how often a fixture is run:
function(default)classmodulesession
@pytest.fixture(scope="module")
def db_connection():
return create_database_connection()Running Tests #
Run All Tests #
pytestRun Specific File #
pytest test_file.pyRun Specific Test #
pytest test_file.py::test_functionVerbose Output #
pytest -vTest Discovery #
Check Collected Tests #
pytest --collect-onlyIgnore Files/Directories #
Add a pytest.ini file:
[pytest]
addopts = --maxfail=3 --disable-warnings
norecursedirs = .git venvParameterized Tests #
Test multiple input values using @pytest.mark.parametrize:
@pytest.mark.parametrize("input,expected", [
(1, 2),
(2, 4),
(3, 6)
])
def test_double(input, expected):
assert input * 2 == expectedDebugging #
Drop Into Debugger on Failure #
pytest --pdbPrint Statements #
Use -s to show print statements:
pytest -sPlugins #
Extend pytest with plugins:
pip install pytest-cov # For coverage reportingExample usage:
pytest --cov=my_moduleUseful Plugins #
pytest-mock: Mocking library integration.pytest-django: Django testing support.pytest-xdist: Run tests in parallel.
Skipping and Expected Failures #
Skip a Test #
@pytest.mark.skip(reason="Not implemented")
def test_placeholder():
assert FalseConditionally Skip #
@pytest.mark.skipif(sys.version_info < (3, 8), reason="Requires Python 3.8")
def test_new_feature():
assert TrueExpected Failures #
@pytest.mark.xfail(reason="Known bug")
def test_known_issue():
assert FalseTest Coverage #
Install Coverage Plugin #
pip install pytest-covRun Tests with Coverage #
pytest --cov=my_moduleGenerate HTML Report #
pytest --cov=my_module --cov-report=htmlUsing pytest-mock
#
Mocking with pytest-mock
#
Use pytest-mock to simplify mocking in your tests:
pip install pytest-mockExample:
def test_mock_function(mocker):
mock_function = mocker.patch("module_name.function_name")
mock_function.return_value = "mocked_value"
result = module_name.function_name()
assert result == "mocked_value"Checking Exception Handling #
You can use pytest.raises to ensure exceptions are properly handled:
def test_exception_handling():
with pytest.raises(ValueError, match="Invalid input"):
function_that_raises_value_error()Using conftest.py
#
The conftest.py file is a special file used to share fixtures and hooks across multiple test files in a pytest project. Place it in the root directory or any subdirectory of your tests.
Example: Shared Fixture #
Create conftest.py:
import pytest
@pytest.fixture
def shared_fixture():
return "shared resource"Use the fixture in your test files without importing:
def test_shared_fixture(shared_fixture):
assert shared_fixture == "shared resource"Advanced Usage #
- Hooks: Customize pytest behavior, such as modifying command-line options or test discovery.
- Scoped Fixtures: Centralize setup and teardown logic.
Example of a hook in conftest.py:
def pytest_addoption(parser):
parser.addoption("--custom-flag", action="store", default="default_value")
@pytest.fixture
def custom_flag(request):
return request.config.getoption("--custom-flag")Run with:
pytest --custom-flag=some_valueBest Practices #
- Use Fixtures: Reuse setup/teardown code.
- Categorize Tests: Use markers for organization.
- Keep Tests Isolated: Ensure tests do not depend on each other.
- Fail Fast: Use
--maxfail=1during debugging. - Write Descriptive Names: Use meaningful test and function names.
With this cheat sheet, you can start using pytest effectively for your testing needs, including advanced use cases like mocking, shared fixtures, and exception handling. Happy testing!