pytest-csv-params/tests/test_blog_example.py

98 lines
3.3 KiB
Python

"""
Example Code for a blog post on juergen.rocks
=============================================
**Module:** ``tests.test_blog_example``
This is a test example for
`a blog post on juergen.rocks <https://juergen.rocks/blog/articles/data-driven-tests-mit-pytest-csv-params.html>`_.
The example consists of serval helper methods and a lot of configuration for the
:meth:`~pytest_csv_params.decorator.csv_params` decorator.
The CSV file looks like this:
.. literalinclude:: ../../../tests/assets/blog-example.csv
:language: text
You find the CSV file in ``tests/assets/blog-example.csv``.
"""
import re
from os.path import dirname, join
from pytest_csv_params.decorator import csv_params
def get_volume(size_data: str) -> int:
"""
Get the volume from size data, return it as mm³.
Helper method, will be used as a data caster.
:param size_data: String from the CSV file.
:returns: Volume in mm³
:raises: ValueError: When the test data cannot be converted
"""
matcher = re.compile(r"^\D*(?P<l>\d+)\D+(?P<d>\d+)\D+(?P<h>\d+)\D+$").match(size_data)
if matcher is None:
raise ValueError("Bad Test Data") from None
return int(matcher.group("l")) * int(matcher.group("d")) * int(matcher.group("h"))
def get_container_volume(container_size: str) -> int:
"""
Get the container size (remove the unit, as mm³).
Helper method, will be used as a data caster.
:param container_size: String from the CSV file.
:returns: Volume of the container in mm³
:raises: ValueError: When the test data cannot be converted
"""
matcher = re.compile(r"^\D*(?P<size>\d+)\D+$").match(container_size)
if matcher is None:
raise ValueError("Bad Test Data") from None
return int(matcher.group("size")) * 1_000_000_000
@csv_params(
data_file=join(dirname(__file__), "assets", "blog-example.csv"),
id_col="Order-Ref #",
header_renames={
"Anz. Schrauben-Päck.": "anz_schrauben",
"Dim. Schrauben-Päck.": "vol_schrauben",
"Anz. Scheiben-Päck.": "anz_scheiben",
"Dim. Scheiben-Päck.": "vol_scheiben",
"Volumen Container": "vol_container",
},
data_casts={
"anz_schrauben": int,
"anz_scheiben": int,
"vol_schrauben": get_volume,
"vol_scheiben": get_volume,
"vol_container": get_container_volume,
},
)
def test_does_it_fit(
anz_schrauben: int, vol_schrauben: int, anz_scheiben: int, vol_scheiben: int, vol_container: int
) -> None:
"""
A test example that tries to figure out if all the Schrauben and Scheiben fit in the container, and if the smallest
possible container is chosen.
:param anz_schrauben: Number of Schraubenpäckchen
:param vol_schrauben: Volume (mm³) of a single Schraubenpäckchen
:param anz_scheiben: Number of Scheibenpäckchen
:param vol_scheiben: Volume (mm³) of a single Scheibenpäckchen
:param vol_container: Volume (mm³) of the selected container
"""
available_container_sizes = map(lambda x: x * 1_000_000_000, [1, 5, 10])
size_required = (anz_schrauben * vol_schrauben) + (anz_scheiben * vol_scheiben)
# Smallest possible Container ordered?
smallest_possible_container = min(filter(lambda x: x >= size_required, available_container_sizes))
assert vol_container == smallest_possible_container