Skip to main content

A simple pytest extension for creating a named test suite.

Project description

Pytest (Parametrize) Suite

image image image image Test & Lint Coverage Code style: black

A tiny plugin for writing clean, easy-to-read, parametrized tests in pytest.

Why?

Pytest's parametrize is a powerful way to write input-output testing to rapidly expand your test coverage while minimizing the number of test assertions you must write. Unfortunately, as the complexity of your test suite grows, it can become difficult to keep track of individual test cases.

One way to get cleaner test output is by assigning descriptive ids and argnames to each parametrized case. However, the current methodologies available result in either very verbose setup, or difficult-to-track ids and names.

Enter pytest-parametrize-suite. With this marker, you define your test ids and names in-line with the values you intend to pass into your test, keeping your identifiers tightly coupled to your test cases and encouraging a delightful testing experience as a result.

Quickstart

Install With PIP

pip install -U pytest-parametrize-suite

Install With Poetry

poetry add --group=test pytest-parametrize-suite

Using the plugin

The plugin provides a single entrypoint in a pytest marker called suite.

The suite marker takes any number of keyword arguments. Each entry in should be a Mapping of argname->argvalue and all entries should be the same exact shape.

This gives developers the ability to

Example

Given the following module:

# iso8601.py

from __future__ import annotations

import datetime


def iso8601(
    date_obj: datetime.date | datetime.datetime | datetime.time | datetime.timedelta
) -> str:
    """Format a Python date/time object into an ISO8601 string."""

    if isinstance(date_obj, (datetime.date, datetime.time)):
        return date_obj.isoformat()
    if isinstance(date_obj, datetime.timedelta):
        return timedelta_isoformat(date_obj)
    raise ValueError(
        f"Unrecognized value of type: {date_obj.__class__.__name__}: {date_obj}"
    )


def timedelta_isoformat(delta: datetime.timedelta) -> str:
    """Why isn't this part of the stdlib?"""
    usecs = abs(
        (delta.days * 24 * 60 * 60 + delta.seconds) * 1000000 + delta.microseconds
    )
    seconds, usecs = divmod(usecs, 1000000)
    minutes, seconds = divmod(seconds, 60)
    hours, minutes = divmod(minutes, 60)
    days, hours = divmod(hours, 24)
    fmt = f"P{days}DT{hours}H{minutes}M{seconds}.{usecs:06}S"
    return fmt

Writing With pytest-parametrize-suite:

# test_iso8601.py

from __future__ import annotations

import datetime

import pytest

from example.iso8601 import iso8601


@pytest.mark.suite(
    datetime=dict(
        given_date_obj=datetime.datetime(1970, 1, 1),
        expected_date_str="1970-01-01T00:00:00",
    ),
    date=dict(
        given_date_obj=datetime.date(1970, 1, 1),
        expected_date_str="1970-01-01",
    ),
    time=dict(
        given_date_obj=datetime.time(),
        expected_date_str="00:00:00",
    ),
    timedelta=dict(
        given_date_obj=datetime.timedelta(1, 1, 1),
        expected_date_str="P1DT1.000001S",
    )
)
def test_iso8601(given_date_obj, expected_date_str):
    # When
    date_str = iso8601(given_date_obj)
    # Then
    assert date_str == expected_date_str

Writing Without pytest-parametrize-suite:

# test_iso8601.py

from __future__ import annotations

import datetime

import pytest

from example.iso8601 import iso8601


@pytest.mark.parametrize(
    argnames=("given_date_obj", "expected_date_str"),
    argvalues=[
        (datetime.datetime(1970, 1, 1), "1970-01-01T00:00:00"),
        (datetime.date(1970, 1, 1), "1970-01-01"),
        (datetime.time(), "00:00:00"),
        (datetime.timedelta(1, 1, 1), "P1DT1.000001S")
    ],
    ids=["datetime", "date", "time", "timedelta"]
)
def test_iso8601(given_date_obj, expected_date_str):
    # When
    date_str = iso8601(given_date_obj)
    # Then
    assert date_str == expected_date_str

Running the test defined in the example outputs the following:

 pytest test_iso8601.py -v
=============================== test session starts ===============================
platform darwin -- Python 3.11.0, pytest-7.2.1, pluggy-1.0.0 -- /Users/god/Library/Caches/pypoetry/virtualenvs/pytest-parametrize-suite-TGMGi3Zp-py3.11/bin/python
cachedir: .pytest_cache
rootdir: /Users/god/PycharmProjects/pytest-parametrize-suite
plugins: parametrize-suite-23.1.0, cov-4.0.0
collected 4 items                                                                 

src/pytest_parametrize_suite/example.py::test_iso8601[datetime] PASSED      [ 25%]
src/pytest_parametrize_suite/example.py::test_iso8601[date] PASSED          [ 50%]
src/pytest_parametrize_suite/example.py::test_iso8601[time] PASSED          [ 75%]
src/pytest_parametrize_suite/example.py::test_iso8601[timedelta] PASSED     [100%]

================================ 4 passed in 0.02s ================================

As you can see, we get a developer-friendly output for our parametrized tests while minimizing the amount of cognitive overhead it takes to understand and develop our test cases.

Happy testing! :white_check_mark:

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_parametrize_suite-23.1.2.tar.gz (18.1 kB view details)

Uploaded Source

Built Distribution

pytest_parametrize_suite-23.1.2-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

Details for the file pytest_parametrize_suite-23.1.2.tar.gz.

File metadata

  • Download URL: pytest_parametrize_suite-23.1.2.tar.gz
  • Upload date:
  • Size: 18.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.3.2 CPython/3.11.0 Darwin/21.6.0

File hashes

Hashes for pytest_parametrize_suite-23.1.2.tar.gz
Algorithm Hash digest
SHA256 f3e11143d38694e6ddc55876070018351c570df25ce45041eec590191a907d1f
MD5 15106fb4add248e8da417104b048f277
BLAKE2b-256 98aca774673d4a26cd113c4b8e1b9c92a6ef11266db8bd6444be1c9d69c08794

See more details on using hashes here.

File details

Details for the file pytest_parametrize_suite-23.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_parametrize_suite-23.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a3a6258cef97943c8e7321099e903a4f782dac1bb8416d7bef37b9ee334dca2f
MD5 f021078faa29ef6c77eeb1017d3fdffa
BLAKE2b-256 055739f602d4af4f391976e355dc615cdbb0c2a18df1a44af8785d0b69ad49da

See more details on using hashes here.

Supported by

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