You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
8.3 KiB

# pytest-csv-params
A pytest plugin to parametrize data-driven tests by CSV files.
[![Build Status](](
[![PyPI - Downloads](](
[![PyPI - Version](](
[![PyPI - Status](](
[![PyPI - Format](](
## Requirements
- Python 3.8, 3.9 or 3.10
- pytest >= 7.1
There's no operating system dependent code in this plugin, so it should run anywhere where pytest runs.
## Installation
Simply install it with pip...
pip install pytest-csv-params
... or poetry ...
poetry add --dev pytest-csv-params
## Documentation / User Guide
**Detailed documentation can be found under
## Usage: Command Line Argument
| Argument | Required | Description | Example |
| `--csv-params-base-dir` | no (optional) | Define a base dir for all relative-path CSV data files (since 0.1.0) | `pytest --csv-params-base-dir /var/testdata` |
## Usage: Decorator
Simply decorate your test method with `@csv_params` (`pytest_csv_params.decorator.csv_params`) and the following parameters:
| Parameter | Type | Description | Example |
| `data_file` | `str` | The CSV file to use, relative or absolute path | `"/var/testdata/test1.csv"` |
| `base_dir` | `str` (optional) | Directory to look up relative CSV files (see `data_file`); overrides the command line argument | `join(dirname(__file__), "assets")` |
| `id_col` | `str` (optional) | Column name of the CSV that contains test case IDs | `"ID#"` |
| `dialect` | `csv.Dialect` (optional) | CSV Dialect definition (see [Python CSV Documentation]( | `csv.excel_tab` |
| `data_casts` | `dict` (optional) | Cast Methods for the CSV Data (see "Data Casting" below) | `{ "a": int, "b": float }` |
| `header_renames` | `dict` (optional) | Replace headers from the CSV file, so that they can be used as parameters for the test function (since 0.3.0) | `{ "Annual Amount of Bananas": "banana_count", "Cherry export price": "cherry_export_price" }` |
## CSV Format
The default CSV format is:
- `\r\n` as line ending
- All non-numeric fields are surrounded by `"`
- If you need a `"` in the value, use `""` (double quote)
- Fields are separated by comma (`,`)
## Usage Example
This example uses the CSV example from above.
from pytest_csv_params.decorator import csv_params
"part_a": int,
"part_b": int,
"expected_result": int,
def test_addition(part_a, part_b, expected_result):
assert part_a + part_b == expected_result
Shorthand example (no ID col, only string values):
from pytest_csv_params.decorator import csv_params
def test_texts(text_a, text_b, text_c):
assert f"{text_a}:{text_b}" == text_c
### More complex example
This example features nearly all things the plugin has to offer. You find this example also in the test cases, see `tests/`.
The CSV file (`tests/assets/example.csv`):
"Test ID","Bananas shipped","Single Banana Weight","Apples shipped","Single Apple Weight","Container Size"
The Test (`tests/`):
from math import ceil
from os.path import join, dirname
from pytest_csv_params.decorator import csv_params
base_dir=join(dirname(__file__), "assets"),
id_col="Test ID",
"Bananas shipped": "bananas_shipped",
"Single Banana Weight": "banana_weight",
"Apples shipped": "apples_shipped",
"Single Apple Weight": "apple_weight",
"Container Size": "container_size",
"bananas_shipped": int,
"banana_weight": float,
"apples_shipped": int,
"apple_weight": float,
"container_size": int,
def test_container_size_is_big_enough(
bananas_shipped: int, banana_weight: float, apples_shipped: int, apple_weight: float, container_size: int
) -> None:
This is just an example test case for the documentation.
gross_weight = (banana_weight * bananas_shipped) + (apple_weight * apples_shipped)
assert ceil(gross_weight) <= container_size
If you decide not to rename the columns, the test would look like this:
base_dir=join(dirname(__file__), "assets"),
id_col="Test ID",
"Bananas_Shipped": int,
"Single_Banana_Weight": float,
"Apples_Shipped": int,
"Single_Apple_Weight": float,
"Container_Size": int,
def test_container_size_is_big_enough(
Bananas_Shipped: int, Single_Banana_Weight: float, Apples_Shipped: int, Single_Apple_Weight: float, Container_Size: int
) -> None:
## Changelog
- A detailed changelog is here:
## Bugs etc.
Please send your issues to `csv-params_issues` (at) ``. Please include the following:
- Plugin Version used
- Pytest version
- Python version with operating system
It would be great if you could include example code that clarifies your issue.
See []( for details.
## Pull Requests
Pull requests are always welcome. Since this Gitea instance is not open to public, just send an e-mail to discuss options.
Any changes that are made are to be backed by tests. Please give me a sign if you're going to break the existing API and let us discuss ways to handle that.
See []( for details.
## Where are the sources?
The source code is available under [](