py.test like automatic fixture injection for unittest and derivatives

automatic, fixture, injection, unittest
pip install arglinker



arglinker is a py.test like automatic fixture injector for unittest and derivatives.

arglinker works with both Python 2 and 3.

At runtime a test method will be called with arguments that are the return values of respectively named fixture methods.

Fixture methods are normal methods without the test prefix, they can have arguments, which are recursively resolved when used as argument fixture.


from arglinker's test:

Enable fixture injection by using the returned class of the add_test_linker function as TestCase:

import unittest
import arglinker

TestCase = arglinker.add_test_linker(unittest.TestCase)

we can now define fixtures as methods of the class, and other methods can refer to fixtures by naming them as parameters:

class Test_fixture_evaluation(TestCase):

    # fixtures with automatic fixture injection
    def one(self):
        return 1

    def two(self, one):
        return one + one

    def three(self, two, one):
        return one + two

    def five(self, three, two):
        return three + two

    def ten(self, five):
        return five + five

    # tests
    def test_fixture_method_parameters_are_auto_injected(self, ten):
        self.assertEqual(10, ten)

    def test_fixture_methods_are_simple_methods(self):
        self.assertEqual(10, self.ten(five=5))

class Test_fixture_sharing(TestCase):

    # fixtures
    def value(self):
        return object()

    def implicit_value(self, value):
        return value

    # test
    def test_fixtures_are_evaluated_only_once_per_tests(
        self, value, implicit_value
        # calling value twice returns different objects
        self.assertIsNot(self.value(), self.value())
        self.assertIsNot(value, self.value())
        # yet implicit_value is the same as value
        self.assertIs(value, implicit_value)

How does it work?

Test methods are replaced with an enhanced argumentless version of the method, that calls the fixture methods and calls the original method with the appropriate fixtures.

Stdlib's introspection module inspect gives access to argument names and a metaclass does the method replacing at class definition time.

The implementation fits on a page and although uses advanced Python constructs, it is relatively simple - take a look!