Skip to content Skip to sidebar Skip to footer

Same Tests Over Many Similar Data Files

With python and unittest I have this structure of test directory: tests/ __init__.py test_001.py data/ data_001_in.py data_001_out.py where data_001_in.py : the inp

Solution 1:

inspirated in the question nose, unittest.TestCase and metaclass: auto-generated test_* methods not discovered, I solved with a metaclass. First, I change the directory data structure to

├── data
│   ├── __init__.py
│   ├── data001
│   │   ├── __init__.py
│   │   ├── datain.py
│   │   ├── dataout.py
│   └── data002
│       ├── __init__.py
│       ├── datain.py
│       ├── dataout.py
└── metatest.py

Second, I make a metaclass for create new test with the data in the subdirectories and base tests.

import unittest
import os
import copy

defdata_dir():
    return os.path.join(os.path.dirname(__file__), 'data')

defget_subdirs(dir_name):
    """ retorna subdirectorios con path completo"""
    subdirs = []
    for f in os.listdir(dir_name):
        f_path = os.path.join(dir_name, f)
        if os.path.isdir(f_path):
            subdirs.append(f)
    return subdirs

defget_data_subdirs():
    return get_subdirs(data_dir())

defdata_py_load(file_name):
    """ carga diccionario data desde archivo .py """
    name = file_name.split('.py')[0]
    path_name = 'data.' + name
    exec_str = "from {} import *".format(path_name)
    exec(exec_str)
    return data

classTestDirectories(type):

    def__new__(cls, name, bases, attrs):

        subdirs = get_data_subdirs()

        callables = dict([
            (meth_name, meth) for (meth_name, meth) in attrs.items() if
                meth_name.startswith('_test')
        ])

        data = {}
        for d in subdirs:
            data[d] = {}
            data[d]['name'] = d
            out_path = "{}.dataout.py".format(d)
            data[d]['out'] = data_py_load(out_path)
            var_path = "{}.datain.py".format(d)
            data[d]['in'] = data_py_load(var_path)

        for meth_name, meth in callables.items():
            for d in subdirs:
                new_meth_name = meth_name[1:]
                # name of test to add, _test to test
                test_name = "{}_{}".format(new_meth_name, d)
                # deep copy for dictionaries
                testeable = lambda self, func=meth, args=copy.deepcopy(data[d]): func(self, args)
                attrs[test_name] = testeable

        returntype.__new__(cls, name, bases, attrs)

classTestData(unittest.TestCase):

    __metaclass__ = TestDirectories

    def_test_name(self, data):
        in_name = data['in']['name']
        out_name = data['out']['name']
        print in_name, out_name
        self.assertEquals(in_name, out_name)

if __name__ == '__main__':
    unittest.main(verbosity=2)

And, when I run

$ python metatest.py
test_name_data001 (__main__.TestData) ... Alice Alice
ok
test_name_data002 (__main__.TestData) ... Bob Bob
ok

----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

Post a Comment for "Same Tests Over Many Similar Data Files"