Regression tests for people on a tight schedule

Simple way to create regression tests with minimal effort

Regression tests are used to ensure that certain functionality stays the same through time and that no bugs are introduced to a critical component. Writing tests is usually one of the boring parts of a programmer's life. It is not as interesting nor rewarding as coding, unless you find bugs in your software thanks to the tests that you have written. Nonetheless, it is crucial to ensure software's stability. In this short article I will show you how to quickly hack minimal regression tests in python using a simple decorator.

The idea is simple, you want to make sure that a certain function gives you the same results over time, so you can just save the arguments and results and rerun the same function with those arguments to ensure it gives you identical results. Python has built-in serialization done using pickle format, so we can just use that.
This is how the code could look like:

                                
import os
import pickle


def generate_test(func, save_dir=''):
    def generate_and_save(*args, **kwargs):
        with open(os.path.join(save_dir, 'test_{}.pkl'.format(func.__name__)), 'wb') as f:
            result = func(*args, **kwargs)
            pickle.dump((args, kwargs, result), f)
            return """
from {module_name} import {func_name}


def test_{func_name}():
    with open(os.path.join('{save_dir}', 'test_{func_name}.pkl'), 'rb') as f:
        args, kwargs, expected_result = pickle.load(f)
        result = {func_name}(*args, **kwargs)
        assert result == expected_result
            """.format(module_name=func.__module__, func_name=func.__name__, save_dir=save_dir)

    return generate_and_save
                                
                            

Here is an example of how you can use this to generate a test

                                
def simple_function(x, y=None):
    return x, y


print(generate_test(simple_function)(5, y=10))
# Output:
from __main__ import simple_function


def test_simple_function():
    with open(os.path.join('', 'test_simple_function.pkl'), 'rb') as f:
        args, kwargs, expected_result = pickle.load(f)
        result = simple_function(*args, **kwargs)
        assert result == expected_result
                                
                            

As you can see, using this method requires minimal effort from a person to quickly create a regression test. Of course in case of integration tests this becomes a bit harder, but as long as you configure your function properly to connect to the right pieces you can still reuse the same simple logic! Continuous integration made simple!