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

Viewed 13112

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?

5 Answers

The unittest syntax is a workaround for a weakness in how Python has implemented assert. Pytest has another workaround with assertion rewriting that largely fixes this problem in a much better way. It's also BETTER at giving nice error messages for asserts than the assertFoo style asserts.

Use pytest and live a happier and more productive life :P

I did some research about the comparison between the two. From what I've read, including the others' points, here are a few points of advocates of self.assertEqual :

  1. Tests will be run even with -O (optimization)
  2. Test messages are nicer looking, in older versions of python the test might halt and does not show the full stack message
  3. Can provide a log message

Advantages of assert are:

  1. flexible (for e.g., compare one dictionary is part of another dictionary: assert dict1 <= dict2 )
  2. simple & shorter to read

In my opinion,

  1. For optimization, I doubt we run it with -O, so self.assertEqual
  2. I did a small test about the two, it looks like: assert is able to terminate properly, and I am able to see the real values going into the statement (probably it's gotten better after years of evolution, till Python 3.8). But it prints out more traceback messages, which may/may not be useful.

So I think it's ok to use assert in unittest, but it's definitely worth considering self.assertEqual as well

Related