### Testing

#### Take a simple function

```
def factorial(n):
total = 1
while n > 1:
total = total * n
n = n - 1
return total
```

#### Test method 1: call the function

Just call the function a few times with different values and observe the output:

```
print factorial(0)
print factorial(1)
print factorial(2)
print factorial(3)
```

Expect the output:

```
1
1
2
6
```

#### Test method 2: simple boolean tests

Create expressions that call the function and each time compare it to the expected output:

```
print factorial(0) == 1
print factorial(1) == 1
print factorial(2) == 2
print factorial(3) == 6
```

Expect:

```
True
True
True
True
```

If any of these tests return `False`

, you will not know the value that they return and you will need to investigate further, but this introduces the idea of a test that either passes, returning `True`

, or fails, returning `False`

. Unlike the first test method, these are self-contained tests that tell you at a glance whether or not the function is returning the correct value.

#### Interlude: Assertions

Assertions are commonly used inside functions to test for errors, like this:

```
def factorial(n):
assert n >= 0
total = 1
while n > 1:
total = total * n
n = n - 1
return total
```

In this case, the program will terminate if you attempt to evaluate the factorial of a negative number.

Assertions are a useful addition to the process of testing your code, but are not a replacement for creating separate tests outside your functions.

#### Test method 3: The “Udacity” method

```
def test():
test_cases = [(0,1),
(1,1),
(2,2),
(3,6)]
for (arg, answer) in test_cases:
result = factorial(arg)
if result != answer:
print "Test with data:", arg, "failed with result ", result
else:
print "Test case passed!"
test()
```

This has the advantages over simple one-line assertions, of allowing you to easily add new test cases and of allowing you to print more information when a test fails.

#### Test method 4: unittest

`unitest`

is the standard Python unit testing framework.

```
import unittest
class FactorialTest(unittest.TestCase):
def test(self):
self.assertEqual(factorial(0), 1)
self.assertEqual(factorial(1), 1)
self.assertEqual(factorial(2), 2)
self.assertEqual(factorial(3), 6)
if __name__ == '__main__':
unittest.main()
```

You can return to this after we have looked at object-oriented programming, when `class`

and `self`

will make more sense.

#### Test method 5: doctest

```
def factorial(n):
"""Return the factorial of n, an exact integer >= 0
>>> [factorial(n) for n in range(6)]
[1, 1, 2, 6, 24, 120]
"""
total = 1
while n > 1:
total = total * n
n = n - 1
return total
if __name__ == "__main__":
import doctest
doctest.testmod()
```

You can write human-readable comments in your code, which with the magic of `>>>`

, will execute the code in your comments and check that the output is the same as following line.

#### Other methods

This quick summary does not even begin to exhaust the possible ways of testing in Python. As your applications gets more complex, other testing libraries are available to help you manage that complexity. If you are curious, take a look at `pytest`

, `nose`

, `tox`

, `unittest2`

and `mock`

.