On the one hand we have automated tests which check one specific example. On the other, we have property-based tests à la QuickCheck where we provide the property while the framework provides the examples, but we might have to explain how examples should be generated.
Somewhere between these two extremes lies the possibility of writing a single test or property and running it on multiple user-provided examples. What utilities exist in the Haskell testing landscape that help with writing such parametrized tests?
As a concrete example, here is how it might be done in Python's pytest. I want to check that the len function gives the correct output for a variety of inputs. This can be done by writing a single test that checks that the length of some input is what the tester expects it to be, and parametrizing the test with numerous examples of inputs and corresponding expected results.
from pytest import mark
param = mark.parametrize
@param('input, expected',
(('' , 0),
('a' , 1),
('b' , 1),
('ab', 2),
('xx', 3), # deliberate mistake
('xyz', 3),
('aaabc', 5)
))
def test_len(input, expected):
assert len(input) == expected
Which produces ouptut like this:
len_test.py::test_len[-0] PASSED [ 14%]
len_test.py::test_len[a-1] PASSED [ 28%]
len_test.py::test_len[b-1] PASSED [ 42%]
len_test.py::test_len[ab-2] PASSED [ 57%]
len_test.py::test_len[xx-3] FAILED [ 71%] (appears red)
len_test.py::test_len[xyz-3] PASSED [ 85%]
len_test.py::test_len[aaabc-5] PASSED [100%]
========================= FAILURES ==========================
______________________ test_len[xx-3] _______________________
len_test.py:15: in test_len
assert len(input) == expected
E AssertionError: assert 2 == 3
E + where 2 = len('xx')
============ 1 failed, 6 passed in 0.04 seconds =============
Is there something similar in Haskell?