Closed crazy25000 closed 3 years ago
I'm not too big on pytest.
Nor excessive parameterization. It's a question of rewriting:
assert something(1)
assert something(2)
into:
for i in (1,
2):
assert something(i)
and both have their uses. Besides, Unittest has subtests, and we do too: https://github.com/kernc/backtesting.py/blob/a49122c72b8e0dd9b30104957638640653c2c113/backtesting/test/_test.py#L555-L561
Have you found any particular deficiencies in functional coverage of our existing tests, or what "boilerplate utils for testing" have you had in mind?
I wouldn't say deficiencies, but we could improve them. Like instead of testing the optimization feature one case per function: https://github.com/kernc/backtesting.py/blob/73e1534428fc2db9e681030862133b5067508520/backtesting/test/_test.py#L505-L508
We could parametrize it so that we test all of them at the same time with one method and pass the args/expected values for these cases:
Since you've already made up your mind with pytest
, going to close this.
Just don't think the small extra utility justifies switching over existing tests, which work nicely.
Parametrization bids coupling, and coupled code is hard to modify. Particularly with the test cases you reference, I don't see how in the world you'd suggest to factor them onto a common denominator and still retain anywhere near the current clarity. :flushed:
Instead of filling the whole hyperspace of possibilities (and tests running for good fifty minutes), I guess I'm content with small, self-contained, functional tests. So far it hasn't proved a tragedy.
As an example of reasonable parametrization, have you seen the coroutine-based test class? It works quite well with strategies that do just a one-off or a particular sequence of actions, and the boilerplate is pretty thin. https://github.com/kernc/backtesting.py/blob/73e1534428fc2db9e681030862133b5067508520/backtesting/test/_test.py#L411-L502
Info
I recommend using pytest for unit testing instead of using the builtin library exclusively. We would benefit from fixtures, parametrization - especially useful for all the possible combinations of parameters, it supports Pythons internal unit tests out of the box, and should reduce boilerplate or having to create utils for testing.
Links
General examples: https://docs.pytest.org/en/stable/example/index.html Parametrize examples: https://docs.pytest.org/en/stable/example/parametrize.html#paramexamples
Example Cases
Here are a few example unit tests I have for my custom backtester:
Example 1 - Function
Example 1 - Unit tests
Here's another example with multiple tests for a strategy using parametrization for more resilient testing. This was useful to speed up testing so I didn't have to duplicate or write custom utils.
Example 2 - Global fixtures available to every unit test if needed
Example 2 - Local fixture available to unit tests in specific folder
Example 2 - Unit tests