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'></foo>")
assertEqualGraphs(want, got, exact=True)[source]

Assert that two RDF graphs are identical (isomorphic).

  • 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.

  • 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, tidy_xhtml=False)[source]

Assert that two xml trees are canonically identical.

  • 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, subset=False, filterdir='entries')[source]

Assert that two directory trees contains identical files

  • 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
  • subset (bool) – If True, require only that files in want is a subset of files in got (otherwise require that the sets are identical)
  • filterdir – If given, don’t compare the parts of the tree that starts with filterdir
class ferenda.testutil.RepoTesterStore(origstore, downloaded_file=None)[source]

This is an internal class used by RepoTester in order to control where source documents are read from.

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"


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

alias of DocumentRepository

docroot = '/tmp'

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


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
download_test(specfile, basefile=None)[source]

This test is run for each json file found in docroot/source.

distill_test(downloaded_file, rdf_file, docroot)[source]

This test is run once for each basefile found in docroot/downloaded. It performs a full parse, and verifies that the distilled RDF metadata is equal to the TTL files placed in docroot/distilled/.

parse_test(downloaded_file, xhtml_file, docroot)[source]

This test is run once for each basefile found in docroot/downloaded. It performs a full parse, and verifies that the resulting XHTML document is equal to the XHTML file placed in docroot/parsed/.

class ferenda.testutil.Py23DocChecker[source]

Checker to use in conjuction with doctest.DocTestSuite.

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/", line 365, in test_method
    template_method(self, *params)
  File "./", line 6, in my_general_test
    self.assertEqual(parameter, "hello")
AssertionError: 'world' != 'hello'
- world
+ hello
  • 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):

from ferenda.testutil import file_parametrize

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.

  • 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 – A function to be called with the name of each found file. If this function returns True, no test is created
  • wrapper – A unittest decorator like unittest.skip() or unittest.expectedFailure().
  • wrapper – callable (decorator)
ferenda.testutil.parametrize_repotester(cls, include_failures=True)[source]

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

  • cls – The RepoTester-based class to create tests on.
  • include_failures (bool) – Create parse/distill tests even if the corresponding xhtml/ttl files doesn’t exist
ferenda.testutil.testparser(testcase, parser, filename)[source]

Helper function to test FSMParser based parsers.