[TIP] Parametrize tests for unit or integration testing

Mateusz Łoskot mateusz at loskot.net
Mon Feb 3 16:25:17 PST 2014

On 3 February 2014 12:01, Andres Riancho <andres.riancho at gmail.com> wrote:
> Doesn't sound really hard. This code won't work but will give you the
> basic idea:
> class BaseTest(object):
>     ClassUnderTest = None
>     def test_foo(self):
>         inst = self.ClassUnderTest()
>         x = foo(inst)
>         self.assertEqual(x, -1)
> class TestWithMock(TestCase, BaseTest):
>     ClassUnderTest = Mock()
> class TestWithReal(TestCase, BaseTest):
>     ClassUnderTest = RealStuff()

No, it doesn't indeed.

In my case, however, my SUT is not a class, so the overall picture is
slightly more complex.
My tests are focused on behaviours, not classes.

I have a module/package which defines large number of functions, a few
types too.
Each tested behaviour is realised by single or multiple functions from
that module,
i.e. 2-4 functions called in sequence to achieve certain behaviour.

So far, for functions taking part in particular behaviour under test,
I've been creating
stubs - with minimal implementation, and
mocks - configured i.e. with return value which then are used to
assert certain invocations.

So, for example:

def test_foo(self):
    # Arrange
    # stub with minimal definitions, required, as called inside foo
    self.mod.bar = Mock()
    self.mod.goo = Mock()
    # mock
    self.mod.foo = Mock(return_value=-1)
    # Act
    x = foo()
    # Assert (may be based on return value or particular invocation w/
    self.assertEqual(x, -1)

This technique has worked well, but such fine-grained subsets of
configurations of stubs/mocks
per tests make it difficult to parametrise the general test case or suite.

Your example gives me an idea though.
I can move the whole # Arrange part, as presented above, to TestWithMock class,
and keep the TestWithReal class without it.
Then, the #Arrange part can set up the whole module attached to self.mod, so the
self.mod would be the holder of injected test case here.

I mean, I think I've got an idea :-) Thanks!

Best regards,
Mateusz  Łoskot, http://mateusz.loskot.net

More information about the testing-in-python mailing list