98 lines
3.3 KiB
Python
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
|