Introduction

This page contains general recommendations and ideas on how to improve the test coverage for the product enpraxis.educommons in a general sense. At this point we have not reviewed particular tests. Instead, we were looking at what kind of tests are available (unit, integration and functional tests); untested portions of code; and current testing practices and tools. A more detailed review is available here.

Ideas

True unit tests and integration unit tests

There are a lot of functionality covered by integration unit tests. This is a very good thing. These tests should be accompanied with true unit tests that test methods and classes in isolation, with none or minimum dependency on external code. To give an example, consider the getDivisionsVocab method in the enpraxis.educommons.content.course.Course class:

    def getDivisionsVocab(self):
        """ Get the list of current divisions and return it as a vocabulary. """
        path = {'query':('/'), }
        brains = self.portal_catalog.searchResults(path=path, Type='Division', sort_on='sortable_title')
        dl = DisplayList()
        dl.add('None', 'None')
        for brain in brains:
            if brain.getId != self.aq_parent.id:
                dl.add(brain.getId, brain.Title)
        return dl

Although this method is called in tests, we should also make sure that it gets unit tested for different values of the brains and self.aq_parent.id variables using dummy and/or mock objects as needed.

Embrace Test-driven development

Before adding new functionality, add a test. Make sure the test fails, and then add functionality to fix the failing test. Adopting this practice will ensure that test coverage only gets better as the product evolves.

Test migrations

Upgrades should also be tested. Products/CMFPlone/tests/testMigrations.py is a great place to look for examples on how to test migrations. Also check the this document for some more information on this matter.

Keep unit tests simple

Unit tests should test a single feature. For example, without going into too much detail, the method testEditing in enpraxis.educommons.tests.test_case_object_edit.testObjectEdit is testing edition for different roles. This is a portion of the code:

        self.EditObjectsAsProducer()
        self.EditObjectsAsManager()
        self.EditObjectsAsQA()
        self.EditObjectsAsPublisher()
        self.EditObjectsAsMember()
        self.EditObjectsAsAnonymous()

This particular test should not be considered a unit test. However, it is probably a good integration test for the editing functionality.

Tests modules organization

It could be useful to have test modules organized in a way that makes clear from file names if the module is about unit or integration tests. This could be achieved by structuring tests in folders or adding sensible prefixes or suffixes to file names.

Practices and Tools

We have modified the product buildout configuration by adding a few tools to run tests and report test coverage. The package z3c.coverage is used to generate HTML reports on test coverage, making much more easy to find untested code.

The use of mock and dummy objects is already a practice in current tests. The next step on this matter would be to make more intensive usage of these techniques.