Ideas you'll find helpful in completing today's challenge are outlined below along with Python code examples.
Unit Testing
The purpose of unit testing it to verify that individual units of code, e.g. functions, work as expected.
When we write unit tests for a function, we want them to cover all major outcomes of the function. This usually includes:
- Testing the function with arguments for which the function is expected to produce different outcomes. For example, let's consider this simple Python function that is intended to return True if and only if the given argument
x
is a positive integer
def is_positive_integer(x):
return x > 0
Then, there are two possble outcomes of the function: True
and False
depending on the value of x
. This implies that good unit tests should cover both of these outcomes, i.e. testing function call with positive x
and with non-positive x
as well.
- Testing the function with arguments that are considered edge cases, i.e. extreme values of parameters, for example, an empty array is an edge case value for the array argument. In our example function:
def is_positive_integer(x):
return x > 0
such edge cases are when x = 0
or x = 1
because they're boundaries for the decision, and probably the values that for which an incorrect implementation of the function might return unexpected results.
- If the function is expected to throw/raise an exception for certain execution patterns, we should also test for this cases. An example of this situation is when someone tries to divide by
0
:
def division(n, divisor):
if divisor == 0:
raise ValueError('division by 0 is not possible')
return n / divisor
In summary, each unit test consists of the data that will be passed as arguments to the function that is tested as well of the expected outcomes of the function call with these arguments.