When you write unit tests, it’s hard to find the right test cases. You want to be certain that you covered all the interesting cases, but you could simply not know or forget one of them. For example, if you unit test a function which receives an integer, you might think about testing 0, 1, and 2. But did you think about negative numbers? What about big numbers?
We were just thinking about a testing strategy for integers. A strategy is a generator of data. The property testing framework hypothesis
offers a lot of strategies for many types. You can install it with pip install hypothesis
.
One thing we can do with those inputs — those tests strategies — is to check if the runtime is acceptable and if the tested function/method does not crash.
It would be better if we compare the output of our function against something. A check for equality is likely not possible, so we need to know a property of our function. An invariant which we always expect to hold. We need to base our test on an inherent property of the function.
To whet your appetite for property-based testing even more:
We have a function factorize(n : int) -> List[int]
which takes an integer and returns the prime factors:
An integer n is called a prime number if it is positive and divisible by exactly two numbers: 1 and n.
We want that the product of returned integers is the number itself. So this is how we design the functions behavior:
An implementation might look like this:
from typing import List
import math
def factorize(number: int) -> List[int]:
if number in [-1, 0, 1]:
return [number]
if number < 0:
return [-1] + factorize(-number)
factors = []
## Treat the factor 2 on its own
while number % 2 == 0:
factors.append(2)
number = number // 2
if number == 1:
return factors
## Now we only need to check uneven numbers
## up to the square root of the number
i = 3
while i <= int(math.ceil(number ** 0.5)) + 1:
while number % i == 0:
factors.append(i)
number = number // i
i += 2
return factors
You might feel a bit uneasy about the condition in
while i <= int(math.ceil(number ** 0.5)) + 1:
#machine-learning #python #data-science #software-engineering #programming