Traditionally, for every piece of code we write (let it be a single function
or class method), we would feed it some arbitrary inputs to make sure that it
works the way we have expected. And this might sound like a reasonable
approach given that everything works as it should and if we do not plan to
make any changes to the code until the end of days. Of course, this is rarely
the case.
Suppose we want to modify our code by refactoring it, or by tweaking it for
improved efficiency: Do we really want to manually type the previous test
cases all over again to make sure we didn't break anything? Or suppose we are
planning to pass our code along to our co-workers: What reason do they have to
trust it? How can we make their life easier by providing evidence that
everything was tested and is supposed to work properly?
Surely, no one wants to spend hours or even days of mundane work to test code
that was inherited before it can be put to use in good conscience.
There must be a cleverer way, an automated and more systematic approach…
This is where unit tests come into play. Once we designed the interface
(_here:_ the in- and outputs of our functions and methods), we can write down
several test cases and let them be checked every time we make changes to our
code - without the tedious work of typing everything all over again, and
without the risk of forgetting anything or by omitting crucial tests simply
due to laziness.
**This is especially important in scientific research, where your whole project depends on the correct analysis and assessment of any data - and there is probably no more convenient way to convince both you and the rightly skeptical reviewer that you just made a(nother) groundbreaking discovery.**
## Main components a typical unit test
In principle, unit testing is really no more than a more systematic way to
automate code testing process. Where the term "unit" is typically defined as
an isolated test case that consists of a the following components:
\- a so-called "fixture" (e.g., a function, a class or class method, or even a
data file)
\- an action on the fixture (e.g., calling a function with a particular input)
\- an expected outcome (e.g., the expected return value of a function)
\- the actual outcome (e.g., the actual return value of a function call)
\- a verification message (e.g., a report whether the actual return value
matches the expected return value or not)
## The different unit test frameworks in Python
In Python, we have the luxury to be able to choose from a variety of good and
capable unit testing frameworks. Probably, the most popular and most widely
used ones are:
\- the [unittest](http://docs.python.org/3.3/library/unittest.html) module -