4.9 KiB
User Guide
This guide will lead you to your first CSV-file parametrized pytest test. It starts with designing your test, preparing your data, writing the test method and finally execute your new test.
The Scenario
Let's say, you have to test this method:
.. literalinclude:: ../../tests/test_docs_example.py
:language: python
:lines: 10,12,18-23,37-41
Parts of the code are from a more complex example written for
a German blog post. The example code
is part of the source code and can be found unter tests/test_blog_example.py
. It is documented as
{mod}~tests.test_blog_example
.
Prepare your data
Your test data resides in an CSV file. CSV files can have different formats, when it comes to:
- Field separators and delimiters
- Quoting
- Line Termination
The class {class}pytest_csv_params.dialect.CsvParamsDefaultDialect
defines a default CSV format that should fit most
requirements:
.. literalinclude:: ../../pytest_csv_params/dialect.py
:language: python
:lines: 5-6,8,18-
You can derive your own CSV format class from there (or from {class}csv.Dialect
), if your files look any other.
Your test data for the method above could look like this:
.. literalinclude:: ../../tests/assets/doc-example.csv
:language: text
:emphasize-lines: 1
- We have a header line in the first line, that names the single columns
- The column names are not good for argument names
- The value in the dimensions column needs to be transformed in order to get tested
- There is a column that tells if an exception is to be expected, and the last two lines expect one
Design and write the test
The test must call the get_smallest_possible_container
method with the right parameters. The CSV file has all
information, but maybe not in the right format. We take care of that in a second.
The test may expect an exception, that should also be considered.
The parameters of the test method should reflect the input parameters for the method under test, and the expectations.
So let's build it:
.. literalinclude:: ../../tests/test_docs_example.py
:language: python
:lines: 14-15,75-81,91-
:emphasize-lines: 4-8
- The test could now get all parameters needed to execute the
get_smallest_container_method
, as well as for the expectations - Based on the expectation for an exception, the test goes in two different directions
Now it's time for getting stuff from the CSV file.
Add the parameters from the CSV file
Here comes the {meth}~pytest_csv_params.decorator.csv_params
decorator. But one step after the other.
.. literalinclude:: ../../tests/test_docs_example.py
:language: python
:lines: 14,16-17,58-81
:emphasize-lines: 5,6,8,16,18
- With the parameter
data_file
you point to your CSV file - With the parameter
id_col
you name the column of the CSV file that contains the test case ID; the test case ID is shown in the execution logs - With the
header_renames
dictionary you define how a column is represented as argument name for your test method; the highlighted example transforms "Number of items" tonumber_of_items
- The
data_casts
dictionary you define how data needs to be transformed to be usable for the test; you can uselambda
s or method pointers; all values from the CSV arrive asstr
All possible parameters are explained under Configuration, or more technically, in the source documentation of
{meth}pytest_csv_params.decorator.csv_params
.
The data_casts
method get_dimensions
looks like the following:
.. literalinclude:: ../../tests/test_docs_example.py
:language: python
:lines: 44,52-55
:emphasize-lines: 4
The method is called during the test collection phase. If the {class}ValueError
raises, the run would end in an error.
Execute the test
There is nothing special to do now. Just run your tests as always. Your run should look like this:
tests/test.py::test_get_smallest_possible_container[Small Container 1] PASSED [ 12%]
tests/test.py::test_get_smallest_possible_container[Small Container 2] PASSED [ 25%]
tests/test.py::test_get_smallest_possible_container[Small Container 3] PASSED [ 37%]
tests/test.py::test_get_smallest_possible_container[Medium Container] PASSED [ 50%]
tests/test.py::test_get_smallest_possible_container[Large Container 1] PASSED [ 62%]
tests/test.py::test_get_smallest_possible_container[Large Container 2] PASSED [ 75%]
tests/test.py::test_get_smallest_possible_container[Not fitting 1] PASSED [ 87%]
tests/test.py::test_get_smallest_possible_container[Not fitting 2] PASSED [100%]
Analyse test failures
- Is it a failure for all test data elements or just for a few?
- When only some tests fail, the Test ID should tell you where to look at