Skip to content

Commit fca259c

Browse files
committed
TST, fix for issue pandas-dev#17978.
Addition of "hypothesis usage" in test cases of tests/reshape/test_util.py as kind of POC. Incorporate review comments. Resolve flake8 warning. Add section for hypothesis in contributing.rst
1 parent 11eb777 commit fca259c

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

doc/source/contributing.rst

+60
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,66 @@ Tests that we have ``parametrized`` are now accessible via the test name, for ex
775775
test_cool_feature.py::test_dtypes[int8] PASSED
776776
test_cool_feature.py::test_series[int8] PASSED
777777
778+
Transitioning to ``hypothesis``
779+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
780+
With the transition to pytest, things have become easier for testing by having reduced boilerplate for test cases and also by utilizing pytest's features like parametizing, skipping and marking test cases.
781+
However, one has to still come up with input data examples which can be tested against the functionality. There is always a possibility to skip testing an example which could have failed the test case.
782+
Imagine if some framework could generate random input examples based on the property/specification of the function being tested. That is exactly what hypothesis does by generating the input data based on some set of specifications provided by the user.
783+
e.g suppose we have to test python's sum function for a list of int.
784+
785+
Here is a sample test case using pytest:
786+
.. code-block:: python
787+
import pytest
788+
789+
@pytest.mark.parametrize('seq', [
790+
[0, 0, 0],
791+
[1, 2, 3, 4],
792+
[-3, 5, -8, 23],
793+
[12345678, 9876543, 567894321]
794+
])
795+
def test_sum_using_pytest(seq):
796+
total = 0
797+
for item in seq:
798+
total += item
799+
assert sum(seq) == total
800+
801+
output of test cases:
802+
.. code-block:: shell
803+
collecting ... collected 4 items
804+
pytest_example.py::test_sum_using_pytest[seq0] PASSED [ 25%]
805+
pytest_example.py::test_sum_using_pytest[seq1] PASSED [ 50%]
806+
pytest_example.py::test_sum_using_pytest[seq2] PASSED [ 75%]
807+
pytest_example.py::test_sum_using_pytest[seq3] PASSED [100%]
808+
809+
========================== 4 passed in 0.06 seconds ===========================
810+
811+
812+
Compare it with below example for the same test case using hypothesis.
813+
.. code-block:: python
814+
from hypothesis import strategies as st
815+
from hypothesis import given
816+
817+
818+
@given(st.lists(st.integers()))
819+
def test_sum(seq):
820+
total = 0
821+
for item in seq:
822+
total += item
823+
assert sum(seq) == total
824+
825+
output of test cases:
826+
.. code-block:: shell
827+
collecting ... collected 1 item
828+
hypothesis_example.py::test_sum PASSED [100%]
829+
830+
========================== 1 passed in 0.33 seconds ===========================
831+
832+
The main difference in above example is use of a decorator "@given(st.lists(st.integers()))" which if applied to test case function, generates some random list of int, which is then assigned to parameter of test case.
833+
For more information about hypothesis or in general about property based testing, check below links:
834+
- https://hypothesis.readthedocs.io/en/latest/quickstart.html
835+
- https://hypothesis.works/articles/what-is-property-based-testing/
836+
- http://blog.jessitron.com/2013/04/property-based-testing-what-is-it.html
837+
778838
779839
Running the test suite
780840
----------------------

0 commit comments

Comments
 (0)