I'm trying to write a way of testing some XML files. The XML files describe input into a scientific analysis program where various parameters can be defined. I want to write unittests for my XML files so I know that the program is configured correctly.
I'm currently doing this as a library with a base test class containing various tests and some mixins for subcomponents. But the subcomponents are repeated a number of times so I want the tests to run once for each mixin e.g.:
class BaseTest(object):
xmlfile = '...'
...
class ComponentMixin(object):
xmlid = None #
var = None #
def test_var(self):
assert self.var == "whatever_the_value_is_in self.xmlfile"
# ... and a number of other tests and variables.
... now for each analysis there can be a number of components defined with different parameters. I'm hoping to do something like this --
class MyFirstComponentMixin(ComponentMixin):
xmlid = 'component1'
var = 'one'
class MySecondComponentMixin(ComponentMixin):
xmlid = 'component2'
var = 'two'
class MyTest(BaseTest, MyFirstComponentMixin, MySecondComponentMixin, unittest.TestCase):
xmlfile = '...'
... but the problem is that test_var will only be called for component2 and not component2. Is there a way around this, or a better solution?
As you were advised in comment: composition is better solution for your problem than inheritance. The idea is to define multiple standalone TestCase
s (parts) for pieces of the XML file and then compose them into single TestSuite
(composite).
Library
It is a base class for part.
class BaseTestCase(unittest.TestCase):
xmlfile = None # will be set by containing test suite
It is an abstract component test case implementation.
class ComponentTestCase(BaseTestCase):
xmlid = None
var = None
def test_var(self):
assert self.var == "whatever_the_value_is_in self.xmlfile"
It is a base for our composite. It defines convenient copying of the xmlfile
from composite to its parts.
class BaseTestSuite(unittest.TestSuite):
xmlfile = None
def addTest(self, test):
if isinstance(test, BaseTestCase):
test.xmlfile = self.xmlfile
super(BaseTestSuite, self).addTest(test)
Usage
It is specific part, which tests some specific aspect of the XML:
class MySpecificTestCase(BaseTestCase):
def test_something_specific(self):
self.assertEqual(4, 2 + 2)
These are parts, which test particular components:
class MyFirstComponentTestCase(ComponentTestCase):
xmlid = 'component1'
var = 'one'
class MySecondComponentTestCase(ComponentTestCase):
xmlid = 'component2'
var = 'two'
Here is a composite with XML you want to test.
class MyTest(BaseTestSuite):
xmlfile = '<some_xml></some_xml>'
We define load_tests to return TestSuite
with all TestCase
s included.
def load_tests(loader, standard_tests, pattern):
return MyTest((
loader.loadTestsFromTestCase(MySpecificTestCase),
loader.loadTestsFromTestCase(MyFirstComponentTestCase),
loader.loadTestsFromTestCase(MySecondComponentTestCase)
))
This approach has one limitation: you can't test few XML files from the single Python file. Basically you can, but output won't help you to identify, which XML file is broken.
Your case is a bit tricky. unittest
were designed to test code, not data. Maybe validation against XML schema is what you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With