Skip to main content

Provides a marker to reference acceptance criteria from PyTest tests through annotations

Project description

pytest-mark-ac

A pytest plugin that provides a marker to reference acceptance criteria from tests through annotations. This plugin modifies test node IDs to include acceptance criteria references, enabling traceability between tests and user stories/acceptance criteria.

Installation

From Source

# Clone the repository
git clone https://gitlab.com/Kencho1/pytest-mark-ac
cd pytest-mark-test

# Install in development mode
pip install -e .

# Or build and install
pip install .

From PyPI

pip install pytest-mark-ac

Usage

The plugin automatically registers when installed. Use the @pytest.mark.ac and @pytest.mark.acs decorators to annotate tests with acceptance criteria references.

Basic Syntax

Single AC reference

Adds a single AC reference.

@pytest.mark.ac(story_id, criterion_id, ref_prefix="ac", ref_suffix="")

Parameters:

  • story_id (int): The user story ID
  • criterion_id (int): The acceptance criterion ID
  • ref_prefix (str, optional): Prefix for the reference (default: "ac")
  • ref_suffix (str, optional): Suffix for the reference (default: "")

Effect: Appends __<ref_prefix><story_id>_<criterion_id><ref_suffix> to the test node ID

Multiple AC references for the same story

Adds several ACs of the same story.

@pytest.mark.acs(story_id, criteria_ids, ref_prefix="ac", ref_suffix="")

Parameters:

  • story_id (int): The user story ID
  • criteria_ids (Sequence[int]): The list of acceptance criteria IDs
  • ref_prefix (str, optional): Prefix for the reference (default: "ac")
  • ref_suffix (str, optional): Suffix for the reference (default: "")

Effect: Appends __<ref_prefix><story_id>_<criterion_id><ref_suffix> to the test node ID for each criterion_id in criteria_ids

Implicit AC references

Adds AC references from the test unit identifier, looking for segments with the form __ac<story_id:int>_<criterion_id:int>.

def test_something__ac1_2(...): # Marks the test with ac(story_id=1, criterion_id=2, ref_prefix="ac", ref_suffix="")

Use Cases and Examples

Use Case 1: Simple Function Test

Link a single test to multiple acceptance criteria:

import pytest

@pytest.mark.acs(1, [1, 2, 3])
def test_user_login():
    # Test implementation
    assert True

Result: Test node ID becomes test_file.py::test_user_login__ac1_1__ac1_2__ac1_3

Note range can be used for sequential ACs as well:

import pytest

@pytest.mark.acs(1, *range(1, 4))
def test_user_login():
    # Test implementation
    assert True

also becomes test_file.py::test_user_login__ac1_1__ac1_2__ac1_3

Use Case 2: Parametrized Tests with Different Criteria

Apply different acceptance criteria to individual parametrized test cases:

from contextlib import nullcontext

@pytest.mark.ac(1, 1)  # Applies to all test cases
@pytest.mark.parametrize(
    'a,b,expected',
    [
        pytest.param(4, 2, nullcontext(2), marks=pytest.mark.ac(2, 1)),
        pytest.param(5, 1, nullcontext(5), marks=pytest.mark.acs(2, [1, 2])),
        pytest.param(3, 2, nullcontext(1.5), marks=pytest.mark.ac(2, 3)),
        pytest.param(3, 0, pytest.raises(ZeroDivisionError), marks=pytest.mark.ac(2, 4)),
    ],
)
def test_division(a, b, expected):
    with expected as exp_result:
        assert (a / b) == exp_result

Result:

  • test_division[4-2-expected0]__ac1_1__ac2_1
  • test_division[5-1-expected1]__ac1_1__ac2_1__ac2_2
  • test_division[3-2-expected2]__ac1_1__ac2_3
  • test_division[3-0-expected3]__ac1_1__ac2_4

Use Case 3: Custom Reference Format

Customize the reference format for your organization's conventions:

@pytest.mark.acs(123, [5, 6], ref_prefix="AC", ref_suffix="_v1")
def test_feature():
    assert True

Result: Test node ID becomes test_file.py::test_feature__AC123_5_v1__AC123_6_v1

Use Case 4: Testing Edge Cases with Acceptance Criteria

@pytest.mark.parametrize(
    'value,expected',
    [
        pytest.param(0, True, marks=pytest.mark.ac(5, 1)),  # Zero case
        pytest.param(-1, True, marks=pytest.mark.ac(5, 2)),  # Negative case
        pytest.param(100, False, marks=pytest.mark.ac(5, 3)),  # Boundary case
    ],
)
def test_validation(value, expected):
    assert validate(value) == expected

Use Case 5: Multiple Stories on One Test

A test can verify acceptance criteria from multiple user stories:

@pytest.mark.acs(10, [1, 2])  # Story 10, criteria 1-2
@pytest.mark.ac(11, 3)     # Story 11, criterion 3
def test_integrated_feature():
    # Tests functionality spanning multiple stories
    assert True

Result: test_file.py::test_integrated_feature__ac10_1__ac10_2__ac11_3

Running Tests with Acceptance Criteria

# Run all tests (shows modified node IDs)
pytest -v

# Run tests for specific acceptance criterion
pytest -v -m "ac(story_id=1, criterion_id=!)"

# Run tests for specific story
pytest -v -m "ac(story_id=5)"

# Show test collection without running
pytest --collect-only

Benefits

  • Traceability: Direct link between tests and acceptance criteria
  • Test Reports: Node IDs in reports show which criteria are covered
  • Selective Execution: Run tests by acceptance criteria using -m flag
  • Documentation: Tests serve as executable documentation of acceptance criteria
  • Duplicate Prevention: Automatically removes duplicate criteria references

Requirements

  • Python >= 3.11
  • pytest >= 9.0.0

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_mark_ac-1.1.1.tar.gz (5.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_mark_ac-1.1.1-py3-none-any.whl (6.4 kB view details)

Uploaded Python 3

File details

Details for the file pytest_mark_ac-1.1.1.tar.gz.

File metadata

  • Download URL: pytest_mark_ac-1.1.1.tar.gz
  • Upload date:
  • Size: 5.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.1

File hashes

Hashes for pytest_mark_ac-1.1.1.tar.gz
Algorithm Hash digest
SHA256 f829ecf307ae2d36b19e91693a52949c4331248028491d645bfb8515b8b22455
MD5 523ed8eaba4acc9b8edde2bf2e9e9526
BLAKE2b-256 32d657077ed041389d86e7253483ebf6e38dae7ff04659568e4762d735e2843a

See more details on using hashes here.

File details

Details for the file pytest_mark_ac-1.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_mark_ac-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5dee7b2e87c75d2f4090ca299a2069cda7379067ba928861a5e134b7eb66d2b5
MD5 0c17c36a3d2b5d9c89e76cbece620c57
BLAKE2b-256 a716a915a9e52387e8efa57a52e0aaa6d40afef8bb3de7bac9242311f69d6dc3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page