The testutil module

unittest-based classes and accompanying functions to create some types of ferenda-specific tests easier.

class ferenda.testutil.FerendaTestCase[source]

Convenience class with extra AssertEqual methods. Note that even though this method provides unittest.TestCase-like assert methods, it does not derive from TestCase. When creating a test case that makes use of these methods, you need to inherit from both TestCase and this class, ie:

class MyTestcase(unittest.TestCase, ferenda.testutil.FerendaTestCase):
    def test_simple(self):
        self.assertEqualXML("<foo arg1='x' arg2='y'/>", "<foo arg2='y' arg1='x'/>")
assertEqualGraphs(want, got, exact=True)[source]

Assert that two RDF graphs are identical (isomorphic).

Parameters:
  • want – The graph as expected, as an Graph object or the filename of a serialized graph
  • got – The actual graph, as an Graph object or the filename of a serialized graph
  • exact (bool) – Whether to require that the graphs are exactly alike (True) or only if all triples in want exists in got (False)
assertAlmostEqualDatetime(datetime1, datetime2, delta=1)[source]

Assert that two datetime objects are reasonably equal.

Parameters:
  • datetime1 (datetime) – The first datetime to compare
  • datetime2 (datetime) – The second datetime to compare
  • delta (int) – How much the datetimes are allowed to differ, in seconds.
assertEqualXML(want, got, namespace_aware=True)[source]

Assert that two xml trees are canonically identical.

Parameters:
  • want – The XML document as expected, as a string, byte string or ElementTree element
  • got – The actual XML document, as a string, byte string or ElementTree element
assertEqualDirs(want, got, suffix=None, filterdir=u'entries')[source]

Assert that two directory trees contains identical files

Parameters:
  • want (str) – The expected directory tree
  • got (str) – The actual directory tree
  • suffix (str) – If given, only check files ending in suffix (otherwise check all the files
  • filterdir – If given, don’t compare the parts of the tree that starts with filterdir
class ferenda.testutil.RepoTester(methodName='runTest')[source]

A unittest.TestCase-based convenience class for creating file-based integration tests for an entire docrepo. To use this, you only need a very small amount of boilerplate code, and some files containing data to be downloaded or parsed. The actual tests are dynamically created from these files. The boilerplate can look something like this:

class TestRFC(RepoTester):
    repoclass = RFC  # the docrepo class to test
    docroot = os.path.dirname(__file__)+"/files/repo/rfc"

parametrize_repotester(TestRFC)
repoclass

The actual documentrepository class to be tested. Must be overridden when creating a testcase class.

alias of DocumentRepository

docroot = u'/tmp'

The location of test files to create tests from. Must be overridden when creating a testcase class

filename_to_basefile(filename)[source]

Converts a test filename to a basefile. Default implementation attempts to find out basefile from the repoclass being tested (or rather it’s documentstore), but returns a hard-coded basefile if it fails.

Parameters:filename (str) – The test file
Returns:Corresponding basefile
Return type:str
ferenda.testutil.parametrize(cls, template_method, name, params, wrapper=None)[source]

Creates a new test method on a TestCase class, which calls a specific template method with the given parameters (ie. a parametrized test). Given a testcase like this:

class MyTest(unittest.TestCase):
    def my_general_test(self, parameter):
        self.assertEqual(parameter, "hello")

and the following top-level initalization code:

parametrize(MyTest,MyTest.my_general_test, "test_one", ["hello"])
parametrize(MyTest,MyTest.my_general_test, "test_two", ["world"])

you end up with a test case class with two methods. Using e.g. unittest discover (or any other unittest-compatible test runner), the following should be the result:

test_one (test_parametric.MyTest) ... ok
test_two (test_parametric.MyTest) ... FAIL

======================================================================
FAIL: test_two (test_parametric.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./ferenda/testutil.py", line 365, in test_method
    template_method(self, *params)
  File "./test_parametric.py", line 6, in my_general_test
    self.assertEqual(parameter, "hello")
AssertionError: 'world' != 'hello'
- world
+ hello
Parameters:
  • cls – The TestCase class to add the parametrized test to.
  • template_method – The method to use for parametrization
  • name (str) – The name for the new test method
  • params (list) – The parameter list (Note: keyword parameters are not supported)
  • wrapper – A unittest decorator like unittest.skip() or unittest.expectedFailure().
  • wrapper – callable
ferenda.testutil.file_parametrize(cls, directory, suffix, filter=None, wrapper=None)[source]
Creates a test for each file in a given directory. Call with

any class that subclasses unittest.TestCase and which has a method called `` parametric_test``, eg:

class MyTest(unittest.TestCase):
    def parametric_test(self,filename):
        self.assertTrue(os.path.exists(filename))

from ferenda.testutil import file_parametrize

file_parametrize(Parse,"test/files/legaluri",".txt")

For each .txt file in the directory test/files/legaluri, a corresponding test is created, which calls parametric_test with the full path to the .txt file as parameter.

Parameters:
  • cls (class) – TestCase to add the parametrized test to.
  • directory (str) – The path to the files to turn into tests
  • suffix – Suffix of the files that should be turned into tests (other files in the directory are ignored)
  • filter – Will be called with the name of each matching file. If the filter callable returns True, no test is created
  • wrapper – A unittest decorator like unittest.skip() or unittest.expectedFailure().
  • wrapper – callable (decorator)
ferenda.testutil.parametrize_repotester(cls)[source]

Helper function to activate a ferenda.testutil.RepoTester based class (see the documentation for that class).

ferenda.testutil.testparser(testcase, parser, filename)[source]

Helper function to test FSMParser based parsers.