Why is the unittest's assert methods slower than raw assertion?
Question: unittest comes with many assert methods. I did a timeit test on using built-in
Python `assert` and comparison operator vs built-in simple unittest assertion.

    
    
    #!/usr/bin/python
    import timeit
    
    s = """\
    import unittest
    class TestRepomanManExtFunctions(unittest.TestCase):
        def test1(self):
            someObj = object()
            newObj = someObj
            self.assertEqual(someObj, newObj)
    
        def test2(self):
            str1 = '11111111111111111111111111111111111111'
            str2 = '33333333333333333333333333333333333333'
            self.assertNotEqual(str1, str2)
    
    
    if __name__ == '__main__':
        unittest.main()
    
    """
    t = timeit.Timer(stmt=s)
    print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
    
    s2 = """\
    import unittest
    class TestRepomanManExtFunctions(unittest.TestCase):
        def test1(self):
            someObj = object()
            newObj = someObj
            assert someObj == newObj
    
        def test2(self):
            str1 = '11111111111111111111111111111111111111'
            str2 = '33333333333333333333333333333333333333'
            assert str1 != str2
    
    
    if __name__ == '__main__':
        unittest.main()
    
    """
    
    t = timeit.Timer(stmt=s2)
    print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
    

The results are

    
    
    yeukhon@yeukhon-P5E-VM-DO:/tests$ python t.py
    1203.46 usec/pass
    873.06 usec/pass
    yeukhon@yeukhon-P5E-VM-DO:tests$ vim t.py
    yeukhon@yeukhon-P5E-VM-DO:tests$ python t.py
    1300.33 usec/pass
    956.35 usec/pass
    yeukhon@yeukhon-P5E-VM-DO:tests$ python t.py
    1208.82 usec/pass
    865.18 usec/pass
    

One advantage of using the unittest's built-in assert methods is that it tells
the user what is actually being compared. An example from of my actual tests:

    
    
    ======================================================================
    FAIL: test_000_write_to_file_directory_not_exist (__main__.TestRepomanManExtFunctions)
    Test writing content to a new file whose parent directory
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1224, in patched
        return func(*args, **keywargs)
      File "test_ext.py", line 71, in test_000_write_to_file_directory_not_exist
        self.assertNotEqual(mk_exists.call_args_list, exists_call_list)
    AssertionError: [call('/tmp/test/fake/')] == [call('/tmp/test/fake/')]
    

Here is using simple `assert X = Y`

    
    
    ======================================================================
    FAIL: test_000_write_to_file_directory_not_exist (__main__.TestRepomanManExtFunctions)
    Test writing content to a new file whose parent directory
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1224, in patched
        return func(*args, **keywargs)
      File "test_ext.py", line 72, in test_000_write_to_file_directory_not_exist
        assert exists_call_list != mk_exists.call_args_list
    AssertionError
    

Besides this advantage, what other nice things can we do by utilising the
built-in `self.assert_*(...)`?

Why is the raw faster? I know accessing attribute and checking against a class
is generally slower. But I want to know what's going on too? I hope this is a
valid question.

Thanks


Answer: Probably the assert* function is slower because there is overhead in calling
it (pushing parameters to stack, calling, popping return address from stack
etc.), compared to the assert keyword which is executed inline. The assert*
functions have some other nice properties as you have mentioned, like printing
the expected and actual value.

Are you asking out of curiosity or is this an actual problem? I'd be surprised
to see any situation where the speed of asserts is a bottleneck.

