In this post, I explore the differences between the unittest boolean assert methods assertTrue and assertFalse and the assertIs identity assertion.

Definitions Here’s what the unittest module documentation currently notes about assertTrue and assertFalse , with the appropriate code highlighted: assertTrue(expr, msg=None) assertFalse(expr, msg=None) Test that expr is true (or false). Note that this is equivalent to bool ( expr ) is True and not to expr is True (use assertIs(expr, True) for the latter). Mozilla Developer Network defines truthy as: A value that translates to true when evaluated in a Boolean context. In Python this is equivalent to: bool ( expr ) is True Which exactly matches what assertTrue is testing for. Therefore the documentation already indicates assertTrue is truthy and assertFalse is falsy. These assertion methods are creating a bool from the received value and then evaluating it. It also suggests that we really shouldn’t use assertTrue or assertFalse for very much at all.

What does this mean in practice? Let’s use a very simple example - a function called always_true that returns True . We’ll write the tests for it and then make changes to the code and see how the tests perform. Starting with the tests, we’ll have two tests. One is “loose”, using assertTrue to test for a truthy value. The other is “strict” using assertIs as recommended by the documentation: import unittest from func import always_true class TestAlwaysTrue ( unittest . TestCase ): def test_assertTrue ( self ): """ always_true returns a truthy value """ result = always_true () self . assertTrue ( result ) def test_assertIs ( self ): """ always_true returns True """ result = always_true () self . assertIs ( result , True ) Here’s the code for our simple function in func.py : def always_true (): """ I'm always True. Returns: bool: True """ return True When run, everything passes: always_true returns True ... ok always_true returns a truthy value ... ok ---------------------------------------------------------------------- Ran 2 tests in 0.004s OK Happy days! Now, “someone” changes always_true to the following: def always_true (): """ I'm always True. Returns: bool: True """ return 'True' Instead of returning True (boolean), it’s now returning string 'True' . (Of course this “someone” hasn’t updated the docstring - we’ll raise a ticket later.) This time the result is not so happy: always_true returns True ... FAIL always_true returns a truthy value ... ok ====================================================================== FAIL: always_true returns True ---------------------------------------------------------------------- Traceback (most recent call last): File "/tmp/assertttt/test.py", line 22, in test_is_true self.assertIs(result, True) AssertionError: 'True' is not True ---------------------------------------------------------------------- Ran 2 tests in 0.004s FAILED (failures=1) Only one test failed! This means assertTrue gave us a false-positive. It passed when it shouldn’t have. It’s lucky we wrote the second test with assertIs . Therefore, just as we learned from the manual, to keep the functionality of always_true pinned tightly the stricter assertIs should be used rather than assertTrue .

Use assertion helpers Writing out assertIs to test for True and False values is not too lengthy. However, if you have a project in which you often need to check that values are exactly True or exactly False , then you can make yourself the assertIsTrue and assertIsFalse assertion helpers. This doesn’t save a particularly large amount of code, but it does improve readability in my opinion. def assertIsTrue ( self , value ): self . assertIs ( value , True ) def assertIsFalse ( self , value ): self . assertIs ( value , False )