{"id":17305099,"url":"https://github.com/seandstewart/pytest-parametrize-suite","last_synced_at":"2025-07-14T15:08:15.493Z","repository":{"id":97741521,"uuid":"589360789","full_name":"seandstewart/pytest-parametrize-suite","owner":"seandstewart","description":"A delightful little pytest plugin for writing clean, readable, parametrized tests.","archived":false,"fork":false,"pushed_at":"2023-01-19T13:15:37.000Z","size":47,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-16T00:15:56.212Z","etag":null,"topics":["pytest","pytest-plugin","testing","testing-tools"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seandstewart.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-01-15T22:48:03.000Z","updated_at":"2024-12-30T22:27:39.000Z","dependencies_parsed_at":"2023-03-07T07:30:50.297Z","dependency_job_id":null,"html_url":"https://github.com/seandstewart/pytest-parametrize-suite","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/seandstewart/pytest-parametrize-suite","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seandstewart%2Fpytest-parametrize-suite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seandstewart%2Fpytest-parametrize-suite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seandstewart%2Fpytest-parametrize-suite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seandstewart%2Fpytest-parametrize-suite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seandstewart","download_url":"https://codeload.github.com/seandstewart/pytest-parametrize-suite/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seandstewart%2Fpytest-parametrize-suite/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265311871,"owners_count":23745161,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pytest","pytest-plugin","testing","testing-tools"],"created_at":"2024-10-15T11:54:40.593Z","updated_at":"2025-07-14T15:08:15.484Z","avatar_url":"https://github.com/seandstewart.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pytest (Parametrize) Suite\n\n[![image](https://img.shields.io/pypi/v/pytest-parametrize-suite.svg)](https://pypi.org/project/pytest-parametrize-suite/)\n[![image](https://img.shields.io/pypi/l/pytest-parametrize-suite.svg)](https://pypi.org/project/pytest-parametrize-suite/)\n[![image](https://img.shields.io/pypi/pyversions/pytest-parametrize-suite.svg)](https://pypi.org/project/pytest-parametrize-suite/)\n[![image](https://img.shields.io/github/languages/code-size/seandstewart/pytest-parametrize-suite.svg?style=flat)](https://github.com/seandstewart/pytest-parametrize-suite)\n[![Test \u0026 Lint](https://github.com/seandstewart/pytest-parametrize-suite/workflows/Test/badge.svg)](https://github.com/seandstewart/pytest-parametrize-suite/actions)\n[![Coverage](https://codecov.io/gh/seandstewart/pytest-parametrize-suite/branch/main/graph/badge.svg)](https://codecov.io/gh/seandstewart/pytest-parametrize-suite)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n\nA tiny plugin for writing clean, easy-to-read, parametrized tests in pytest.\n\n## Why?\n\nPytest's `parametrize` is a powerful way to write input-output testing to rapidly \nexpand your test coverage while minimizing the number of test assertions you must \nwrite. Unfortunately, as the complexity of your test suite grows, it can become \ndifficult to keep track of individual test cases.\n\nOne way to get cleaner test output is by assigning descriptive `ids` and `argnames` to \neach parametrized case. However, the current methodologies available result in either \nvery verbose setup, or difficult-to-track ids and names.\n\nEnter `pytest-parametrize-suite`. With this marker, you define your test ids and \nnames in-line with the values you intend to pass into your test, keeping your \nidentifiers tightly coupled to your test cases and encouraging a delightful testing \nexperience as a result.\n\n## Quickstart\n\n### Install With PIP\n\n```shell\npip install -U pytest-parametrize-suite\n```\n\n### Install With Poetry\n\n```shell\npoetry add --group=test pytest-parametrize-suite\n```\n\n## Using the plugin\n\nThe plugin provides a single entrypoint in a pytest marker called `suite`. \n\nThe `suite`\nmarker takes any number of keyword arguments. Each entry in should be a Mapping of \n`argname-\u003eargvalue` and all entries should be the same exact shape.\n\nThis gives developers the ability to \n\n#### Example\n\n**Given the following module:**\n\n```python\n# iso8601.py\n\nfrom __future__ import annotations\n\nimport datetime\n\n\ndef iso8601(\n    date_obj: datetime.date | datetime.datetime | datetime.time | datetime.timedelta\n) -\u003e str:\n    \"\"\"Format a Python date/time object into an ISO8601 string.\"\"\"\n\n    if isinstance(date_obj, (datetime.date, datetime.time)):\n        return date_obj.isoformat()\n    if isinstance(date_obj, datetime.timedelta):\n        return timedelta_isoformat(date_obj)\n    raise ValueError(\n        f\"Unrecognized value of type: {date_obj.__class__.__name__}: {date_obj}\"\n    )\n\n\ndef timedelta_isoformat(delta: datetime.timedelta) -\u003e str:\n    \"\"\"Why isn't this part of the stdlib?\"\"\"\n    usecs = abs(\n        (delta.days * 24 * 60 * 60 + delta.seconds) * 1000000 + delta.microseconds\n    )\n    seconds, usecs = divmod(usecs, 1000000)\n    minutes, seconds = divmod(seconds, 60)\n    hours, minutes = divmod(minutes, 60)\n    days, hours = divmod(hours, 24)\n    fmt = f\"P{days}DT{hours}H{minutes}M{seconds}.{usecs:06}S\"\n    return fmt\n\n```\n\n**Writing With pytest-parametrize-suite:**\n\n```python\n# test_iso8601.py\n\nfrom __future__ import annotations\n\nimport datetime\n\nimport pytest\n\nfrom example.iso8601 import iso8601\n\n\n@pytest.mark.suite(\n    datetime=dict(\n        given_date_obj=datetime.datetime(1970, 1, 1),\n        expected_date_str=\"1970-01-01T00:00:00\",\n    ),\n    date=dict(\n        given_date_obj=datetime.date(1970, 1, 1),\n        expected_date_str=\"1970-01-01\",\n    ),\n    time=dict(\n        given_date_obj=datetime.time(),\n        expected_date_str=\"00:00:00\",\n    ),\n    timedelta=dict(\n        given_date_obj=datetime.timedelta(1, 1, 1),\n        expected_date_str=\"P1DT1.000001S\",\n    )\n)\ndef test_iso8601(given_date_obj, expected_date_str):\n    # When\n    date_str = iso8601(given_date_obj)\n    # Then\n    assert date_str == expected_date_str\n\n```\n\n**Writing Without pytest-parametrize-suite:**\n\n```python\n# test_iso8601.py\n\nfrom __future__ import annotations\n\nimport datetime\n\nimport pytest\n\nfrom example.iso8601 import iso8601\n\n\n@pytest.mark.parametrize(\n    argnames=(\"given_date_obj\", \"expected_date_str\"),\n    argvalues=[\n        (datetime.datetime(1970, 1, 1), \"1970-01-01T00:00:00\"),\n        (datetime.date(1970, 1, 1), \"1970-01-01\"),\n        (datetime.time(), \"00:00:00\"),\n        (datetime.timedelta(1, 1, 1), \"P1DT1.000001S\")\n    ],\n    ids=[\"datetime\", \"date\", \"time\", \"timedelta\"]\n)\ndef test_iso8601(given_date_obj, expected_date_str):\n    # When\n    date_str = iso8601(given_date_obj)\n    # Then\n    assert date_str == expected_date_str\n\n```\n\nRunning the test defined in the example outputs the following:\n\n```shell\n❯ pytest test_iso8601.py -v\n=============================== test session starts ===============================\nplatform 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\ncachedir: .pytest_cache\nrootdir: /Users/god/PycharmProjects/pytest-parametrize-suite\nplugins: parametrize-suite-23.1.0, cov-4.0.0\ncollected 4 items                                                                 \n\nsrc/pytest_parametrize_suite/example.py::test_iso8601[datetime] PASSED      [ 25%]\nsrc/pytest_parametrize_suite/example.py::test_iso8601[date] PASSED          [ 50%]\nsrc/pytest_parametrize_suite/example.py::test_iso8601[time] PASSED          [ 75%]\nsrc/pytest_parametrize_suite/example.py::test_iso8601[timedelta] PASSED     [100%]\n\n================================ 4 passed in 0.02s ================================\n```\n\nAs you can see, we get a developer-friendly output for our parametrized tests while \nminimizing the amount of cognitive overhead it takes to understand and develop our test \ncases.\n\nHappy testing! :white_check_mark:\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseandstewart%2Fpytest-parametrize-suite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseandstewart%2Fpytest-parametrize-suite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseandstewart%2Fpytest-parametrize-suite/lists"}