Why do assertions in unittest use TestCase.assertEqual not the assert keyword?

Python's built-in unittest module makes assertions with TestCase.assert* methods:

class FooTest(TestCase):
    def test_foo(self):
        self.assertEqual(1,1)
        self.assertNotEqual(1,2)
        self.assertTrue(True)

I have generally used a testrunner such as nose or py.test which allow use of the built-in assert keyword when making assertions:

assert 1 == 1
assert 1 != 2
assert True

What is the motivation for unittest's TestCase.assert* approach and what are the strengths and weaknesses of this vs asserting with the built-in assert keyword? Are there reasons why unittest's syntax should be favoured?


Solution 1:

The problem with the assert keyword is that it is optimized out, and thus ignored, when Python is run in 'optimized' mode (with the -O argument or with the PYTHONOPTIMIZE environment variable set.) If tests were to use assert then testing with -O would be impossible.

Additionally, the use of the assert methods makes it trivial to report about what the values involved actually were, without having to dig into the stack and the source and figure out what they were supposed to be (which, I believe, is the technique nose and py.test use for this.)

Solution 2:

I don't see a concrete design decision for this. Looking at the unittest docs it states that

the type specific equality function will be called in order to generate a more useful default error message

So I would say it is an implementation decision to help produce more meaningful errors etc.