Skip to content
Phillip Cloud edited this page Jun 19, 2013 · 11 revisions

Typical Imports

import nose
import unittest
import pandas.util.testing as tm

Additional imports

When creating a subclass of unittest.TestCase there are useful instance methods such as self.assertEqual(a, b) that allow you to test the equality of two objects. These are not available as functions in the Python standard library. However, these methods are available as functions in the nose.tools module. To use self.assertEqual(a, b) in a function you would put from nose.tools import assert_equal and then call it wherever you need it.

Important: make sure to document failure conditions (and use the assertRaisesRegexp where necessary to make it clearer which exception you want to get).

Testing using a File

This context manager allows safe read/write access to a temporary file, with a generated filename (or your filename if provided). The file will be automatically deleted when the context block is exited.

with tm.ensure_clean('my_file_path') as path:
    # do something with the path

Testing for Exceptions

Generally, it's not acceptable to just check that something raises Exception, because that tends to mask a lot of errors. For example, if a function's signature changes between releases, you could be catching the wrong kind of error altogether.

Another element that is helpful is to use assertRaisesRegexp (coming very soon) from pandas.util.testing, which allows you to specify a regular expression to match against. The call signature is nearly the same as assertRaises, but it adds an extra positional argument E.g.

assertRaisesRegexp(TypeError, 'literal', int, 'XYZ')
# or another common possibility (originally was PandasError, now changed.)
assertRaisesRegexp(TypeError, 'constructor', DataFrame, 1)

Handling tests requiring network connectivity

In general, network tests are finicky. All tests that involve networking must be marked as "network", either by using the network decorator or the with_connectivity_check decorator from pandas.util.testing.Unless you absolutely need to test that a function/method correctly handles connectivity errors, you should use the network decorator, which will catch all IOErrors (which includes URLError). If you believe that your test case will only fail if you simply aren't connected to the internet, you can use the with_connectivity_test to check:

>>> @with_connectivity_test
... def test_my_function():
...     urllib2.urlopen("funny://rabbithead")
>>> test_my_function()
Traceback (most recent call last)
    ...
URLError...#some message

If you want to have the decorator always raise errors, just pass raise_on_error=True to the network decorator:

>>> @network(raise_on_error=True)
... def test2():
...     raise URLError("WRONG!")
Traceback (most recent call last)
    ...
URLError: WRONG!

Testing for Warnings

To test for warnings, you can use the assert_produces_warning contextmanager, which checks that your code produces a warning.

Probably the most common case is just a test case for a DeprecationWarning:

>>> with assert_produces_warning(DeprecationWarning):
...     some_function_that_raises_deprecation_warning()

With no arguments, it checks that any warning is raised.

    >>> import warnings
    >>> with assert_produces_warning():
    ...     warnings.warn(UserWarning())
    ...

When passed False, it checks that no warnings are raised.

    >>> with assert_produces_warning(False):
    ...     warnings.warn(RuntimeWarning())
    ...
    Traceback (most recent call last):
        ...
    AssertionError: Caused unexpected warning(s): ['RuntimeWarning'].

Finally, if you pass it a warning class, it will check that the specific class of warning was raised and no other.

    >>> with assert_produces_warning(UserWarning):
    ...     warnings.warn(RuntimeWarning())
    Traceback (most recent call last):
        ...
    AssertionError: Did not see expected warning of class 'UserWarning'.
Clone this wiki locally