### Property based testing in a research setting [@drvinceknight](https://twitter.com/drvinceknight)
- Doctests - Unittests - Property based tests

>>> for k in range(10):
...     print(11 * k)
0
11
22
33
44
55
66
77
88
99

					
A number is divisible by 11 if and only if the alternating (in sign) sum of the number’s digits is 0.

$$f(11) = 1-1$$ $$f(22) = 2-2$$ $$f(121) = 1-2+1$$

Doctests

`main.py`

def divisible_by_11(number):
    """
    Uses above criterion to check if number is divisible by 11

    For example:

		>>> import main
		>>> main.divisible_by_11(11)
		True
		>>> main.divisible_by_11(12)
		False

    """
    string_number = str(number)
    alternating_sum = sum((-1) ** i * int(d) for i, d
                           in enumerate(string_number))
    return alternating_sum == 0
                    
$ python -m doctest main.py

>>> import main
>>> for k in range(11):
...     print(main.divisible_by_11(11 * k))
True
True
True
True
True
True
True
True
True
True
True

                    
$ python -m doctest index.html

Examples

Health Warning

Unittests

`test_main.py`

import unittest
import main

class TestDivisible(unittest.TestCase):
    def test_divisible_by_11(self):

        for k in range(10):
            self.assertTrue(main.divisible_by_11(11 * k))
            self.assertFalse(main.divisible_by_11(11 * k + 1))

        # Some more examples
        self.assertTrue(main.divisible_by_11(121))
        self.assertFalse(main.divisible_by_11(123))
                    

$ python -m unittest test_main
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
                    

This is how we break mathematics

Property based testing

`test_property_main.py`

import unittest
import main

from hypothesis import given
from hypothesis.strategies import integers

class TestDivisible(unittest.TestCase):

    @given(k=integers(min_value=1))
    def test_divisible_by_11(self, k):
        self.assertTrue(main.divisible_by_11(11 * k))
                    

$ python -m unittest test_property_main
Falsifying example: test_divisible_by_11(self=, k=19)
F
======================================================================
FAIL: test_divisible_by_11 (test_property_main.TestDivisible)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_property_main.py", line 10, in test_divisible_by_11
    def test_divisible_by_11(self, k):
  File "/usr/local/lib/python2.7/site-packages/hypothesis/core.py", line 502, in wrapped_test
    print_example=True, is_final=True
  File "/usr/local/lib/python2.7/site-packages/hypothesis/executors.py", line 57, in default_new_style_executor
    return function(data)
  File "/usr/local/lib/python2.7/site-packages/hypothesis/core.py", line 103, in run
    return test(*args, **kwargs)
  File "test_property_main.py", line 11, in test_divisible_by_11
    self.assertTrue(main.divisible_by_11(11 * k))
AssertionError: False is not true

----------------------------------------------------------------------
Ran 1 test in 0.022s
                    
`main.py`

def divisible_by_11(number):
    """
	Uses above criterion to check if number is divisible by 11


    For example:

		>>> import main
		>>> main.divisible_by_11(11)
		True
		>>> main.divisible_by_11(12)
		False

	"""
    # Catch the base case:
    if number < 11:
        return number == 0

    string_number = str(number)
    # Using abs as the order of the alternating sum doesn't matter.
    alternating_sum = abs(sum((-1) ** i * int(d) for i, d
                              in enumerate(string_number)))
    # Recursively calling the function
    return divisible_by_11(alternating_sum)
                    

"In the field"

Nashpy

Composite strategies

Axelrod

## Shrinking > "Smallest reproduction of this (this is not a py2 or py3 thing apparently):"
## Data base > "I don't get this when running the tests locally."

hypothesis.readthedocs.org

Property based testing:

Allowing reproducibility of what you have not done yet

@drvinceknight

hypothesis.works