Fundamentals 25 min read

Master Pytest: From Basics to Advanced Fixtures and Allure Reporting

This comprehensive guide walks you through Pytest fundamentals, basic usage, fixture mechanisms, conftest configuration, and advanced features such as Allure report beautification, parameterized data‑driven testing, and YAML integration, providing practical code examples for Python test automation.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Master Pytest: From Basics to Advanced Fixtures and Allure Reporting

We previously covered Python's built‑in unittest framework, which has certain limitations. This article introduces the third‑party framework Pytest, which retains unittest syntax while offering many optimizations.

We will cover Pytest from the following angles:

Pytest basic introduction

Pytest basic usage

Pytest advanced content

Pytest Basic Introduction

First, a brief overview of Pytest and related concepts.

Unit Test Framework

Testing generally includes four types:

Unit testing: testing the smallest software unit (module) for correctness.

Integration testing: testing combined modules, focusing on interfaces.

System testing: testing the whole system, including functionality, performance, and environment.

Acceptance testing: testing against contract‑defined criteria to decide system acceptance.

This article focuses on unit testing:

Python: UnitTest and Pytest are used for unit test automation; Pytest is now mainstream.

Java: TestNG and JUnit are used; TestNG is mainstream.

The main functions of a unit‑test framework are:

Discover test cases

Execute test cases

Determine test results

Generate test reports

Framework Basic Introduction

Key points about Pytest:

Pytest is a mature unit‑test framework with flexibility and simplicity.

It has strong compatibility and ecosystem, integrating with Selenium, Requests, Appium, etc.

It provides better reporting, supporting custom Allure reports and Jenkins CI.

Common Pytest plugins:

pytest‑html: generate HTML reports

pytest‑xdist: multi‑threaded execution

pytest‑ordering: change test execution order

pytest‑rerunfailures: rerun failed tests

allure‑pytest: generate attractive Allure reports

Install all plugins at once:

# Create a file requestment.txt with plugin names
pytest-html
pytest-xdist
pytest-ordering
pytest-rerunfailures

# Install them
pip install -r requestment.txt

Pytest Basic Usage

Default test case naming rules:

# Test modules must be placed in a testcases folder and start or end with "test_"
# Example module names
test_demo1.py
demo2_test.py

# Test classes must start with "Test" and cannot have an __init__ method
class TestDemo1:
    pass
class TestLogin:
    pass

# Test methods must start with "test_"

def test_demo1(self):
    pass

def test_demo2(self):
    pass

# Example test case
class TestDemo:
    def test_demo1(self):
        print("Test case 1")
    def test_demo2(self):
        print("Test case 2")

Running tests:

# pytest.ini configuration (place in project root)
[pytest]
addopts = -vs
testpaths = ./testcases
python_files = test_*.py
python_classes = Test*
python_functions = test_*
markers =
    smoke: smoke tests
    product_manage: product management tests

# Command line examples
pytest -vs                     # verbose and show prints
pytest -vs -n=2                # run with 2 parallel workers (requires pytest‑xdist)
pytest -vs --reruns=2          # rerun failed tests (requires pytest‑rerunfailures)
pytest -vs -x                  # stop after first failure
pytest -vs --maxfail=2         # stop after two failures
pytest -vs --html ./reports/result.html   # generate HTML report (requires pytest‑html)
pytest -vs -k "keyword"       # run tests whose names contain keyword
pytest -vs -k "a or b"        # run tests matching a or b
pytest -vs -k "a and b"       # run tests matching both a and b
pytest -vs -m smoke            # run tests marked as smoke

Skipping tests (same as unittest):

# Skip without reason
@pytest.mark.skip(reason="No reason")

def test_demo1(self):
    print("Skipped")

# Skip conditionally
workage2 = 5
workage3 = 20

@pytest.mark.skipif(workage2 < 10, reason="Experience less than 10 years")
def test_demo2(self):
    print("Skipped due to experience")

@pytest.mark.skipif(workage3 < 10, reason="Experience less than 10 years")
def test_demo3(self):
    print("Executed")

Pytest Setup and Teardown

Understanding fixtures for pre‑ and post‑actions at different scopes:

Function scope – runs before and after each test function.

Class scope – runs once before and after all methods in a class.

Module scope – runs before and after all tests in a module.

# Function‑level fixture
@pytest.fixture(scope="function")
def exe_database_sql():
    print("Execute SQL query")
    yield
    print("Close DB connection")

# Class‑level fixture
@pytest.fixture(scope="class")
def exe_database_sql():
    print("Execute SQL query")
    yield
    print("Close DB connection")

# Session‑level fixture
@pytest.fixture(scope="session")
def exe_database_sql():
    print("Execute SQL query")
    yield
    print("Close DB connection")

Using fixtures automatically:

# Auto‑use fixture
@pytest.fixture(scope="function", autouse=True)
def exe_database_sql():
    print("Execute SQL query")
    yield
    print("Close DB connection")

Parameterizing fixtures:

# Parameterized fixture with request
@pytest.fixture(scope="function", params=["val1", "val2"], ids=["1", "2"])
def exe_database_sql(request):
    print("Execute SQL query")
    yield request.param
    print("Close DB connection")

conftest.py

The conftest.py file stores shared fixtures. Its location determines the fixture scope:

Root‑level conftest.py – fixtures available to all tests.

Subdirectory conftest.py – fixtures limited to that directory.

# conftest.py at project root
import pytest

@pytest.fixture(scope="function", name="exe_database_sql_name")
def exe_database_sql():
    print("Run before all methods")
    yield
    print("Run after all methods")

Fixture usage in tests (no import needed):

# test_demo1.py
import pytest

class TestDemo1:
    def test_1(self, exe_database_sql_name):
        print("Login success" + exe_database_sql_name)

Pytest Advanced Content

Allure Report Beautification

Allure provides a flexible, lightweight multi‑language test report with a web UI.

# Install Allure command‑line tool and set PATH
# Install pytest plugin
pip install allure-pytest

# Generate Allure JSON files
pytest --alluredir=./temps --clean-alluredir

# Generate HTML report
allure generate ./temps -o ./reports --clean

Parametrize Data‑Driven Testing

Use @pytest.mark.parametrize to drive tests with multiple data sets.

# Single parameter list
@pytest.mark.parametrize('caseinfo', ['A', 'B', 'C'])
def test_01(self, caseinfo):
    print("Token:" + caseinfo)

# Multiple parameters
@pytest.mark.parametrize('arg1,arg2', [['A1','A2'], ['B1','B2']])
def test_01(self, arg1, arg2):
    print("Token:" + str(arg1) + " " + str(arg2))

Combine with YAML files for external data:

# read_yaml function (requires pyyaml)
import os, yaml

def get_obj_path():
    return os.path.dirname(__file__).split('common')[0]

def read_yaml(yamlPath):
    with open(get_obj_path() + yamlPath, mode='r', encoding='utf-8') as f:
        return yaml.load(f, Loader=yaml.FullLoader)

# Use in parametrize
@pytest.mark.parametrize('caseinfo', read_yaml('testcase/user_manage/get_token.yaml'))
def test_01(self, caseinfo):
    print("Token:" + caseinfo)
    print("Name:" + caseinfo['name'])
    print("Method:" + caseinfo['request']['method'])
    print("URL:" + caseinfo['request']['url'])
    print("Data:" + caseinfo['request']['data'])

Overall fixture execution order:

fixture_session > fixture_class > setup_class > fixture_function > setup

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Pythonunit testingpytestAllurefixturesparametrize
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.