mirror of
https://github.com/jbranchaud/til
synced 2026-07-02 23:58:25 +00:00
Add Define Sequence Of Tests With Parametrize Decorator as a Python TIL
This commit is contained in:
@@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/).
|
|||||||
|
|
||||||
For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter).
|
For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter).
|
||||||
|
|
||||||
_1782 TILs and counting..._
|
_1783 TILs and counting..._
|
||||||
|
|
||||||
See some of the other learning resources I work on:
|
See some of the other learning resources I work on:
|
||||||
|
|
||||||
@@ -1058,6 +1058,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
|||||||
- [Create A Dummy DataFrame In Pandas](python/create-a-dummy-dataframe-in-pandas.md)
|
- [Create A Dummy DataFrame In Pandas](python/create-a-dummy-dataframe-in-pandas.md)
|
||||||
- [Create A Range Of Descending Values](python/create-a-range-of-descending-values.md)
|
- [Create A Range Of Descending Values](python/create-a-range-of-descending-values.md)
|
||||||
- [Deduplicate A List Into A Tuple](python/deduplicate-a-list-into-a-tuple.md)
|
- [Deduplicate A List Into A Tuple](python/deduplicate-a-list-into-a-tuple.md)
|
||||||
|
- [Define Sequence Of Tests With Parametrize Decorator](python/define-sequence-of-tests-with-parametrize-decorator.md)
|
||||||
- [Dunder Methods](python/dunder-methods.md)
|
- [Dunder Methods](python/dunder-methods.md)
|
||||||
- [Easy Key-Value Aggregates With defaultdict](python/easy-key-value-aggregates-with-defaultdict.md)
|
- [Easy Key-Value Aggregates With defaultdict](python/easy-key-value-aggregates-with-defaultdict.md)
|
||||||
- [Install With PIP For Specific Interpreter](python/install-with-pip-for-specific-interpreter.md)
|
- [Install With PIP For Specific Interpreter](python/install-with-pip-for-specific-interpreter.md)
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# Define Sequence Of Tests With Parametrize Decorator
|
||||||
|
|
||||||
|
I have a function that I want to test across a bunch of different inputs. That
|
||||||
|
way I can make sure the logic of that function handles all the different
|
||||||
|
scenarios I have in mind.
|
||||||
|
|
||||||
|
While working on [`py-vmt`](https://github.com/jbranchaud/py-vmt), I started by
|
||||||
|
writing a big single test function with a sequence of variable assignments and
|
||||||
|
`assert` statements. Here's my starting point:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def test_format_time_delta_everything():
|
||||||
|
# less than a minute
|
||||||
|
thirty_seconds = timedelta(seconds=30)
|
||||||
|
assert "30s" == format_time_delta(thirty_seconds)
|
||||||
|
|
||||||
|
# one minute exactly
|
||||||
|
one_minute = timedelta(seconds=60)
|
||||||
|
assert "1m" == format_time_delta(one_minute)
|
||||||
|
|
||||||
|
# more than a minute
|
||||||
|
assert "1m30s" == format_time_delta(one_minute + thirty_seconds)
|
||||||
|
|
||||||
|
# bunch of minutes and seconds
|
||||||
|
delta = timedelta(minutes=24, seconds=8)
|
||||||
|
assert "24m8s" == format_time_delta(delta)
|
||||||
|
|
||||||
|
# one hour exactly
|
||||||
|
one_hour = timedelta(hours=1)
|
||||||
|
assert "1h" == format_time_delta(one_hour)
|
||||||
|
|
||||||
|
# more than one hour
|
||||||
|
assert "1h24m" == format_time_delta(one_hour + delta)
|
||||||
|
```
|
||||||
|
|
||||||
|
I knew I would eventually need to break it up into individual test functions,
|
||||||
|
but I couldn't bare to start there because it seemed quite repetitive.
|
||||||
|
|
||||||
|
There is another way to approach this without all the duplication. Pytest comes
|
||||||
|
with [a "parametrize" decorator](https://docs.pytest.org/en/stable/example/parametrize.html). This is
|
||||||
|
used to define a set of test data (and expected values) that will get passed
|
||||||
|
one-by-one to the test function as parameters.
|
||||||
|
|
||||||
|
```python
|
||||||
|
@pytest.mark.parametrize("input,expected", [
|
||||||
|
(timedelta(seconds=30), "30s"),
|
||||||
|
(timedelta(seconds=60), "1m"),
|
||||||
|
(timedelta(seconds=90), "1m30s"),
|
||||||
|
(timedelta(minutes=24, seconds=8), "24m8s"),
|
||||||
|
(timedelta(hours=1), "1h"),
|
||||||
|
(timedelta(hours=1, minutes=24, seconds=8), "1h24m"),
|
||||||
|
])
|
||||||
|
def test_format_time_delta(input, expected):
|
||||||
|
assert format_time_delta(input) == expected
|
||||||
|
```
|
||||||
|
|
||||||
|
I ditch all of the duplication this way. I define a list of tuples that
|
||||||
|
represent my input values and expected values. Then the body of the test can be
|
||||||
|
minimal. And I get a separate test execution for each parameter tuple making it
|
||||||
|
easier to see fine-grained pass/fail results.
|
||||||
Reference in New Issue
Block a user