Continuing in Python's unittest when an assertion fails

前端 未结 12 1590
感情败类
感情败类 2020-11-27 14:03

EDIT: switched to a better example, and clarified why this is a real problem.

I\'d like to write unit tests in Python that continue executing when an assertion fails

12条回答
  •  广开言路
    2020-11-27 14:38

    I liked the approach by @Anthony-Batchelor, to capture the AssertionError exception. But a slight variation to this approach using decorators and also a way to report the tests cases with pass/fail.

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import unittest
    
    class UTReporter(object):
        '''
        The UT Report class keeps track of tests cases
        that have been executed.
        '''
        def __init__(self):
            self.testcases = []
            print "init called"
    
        def add_testcase(self, testcase):
            self.testcases.append(testcase)
    
        def display_report(self):
            for tc in self.testcases:
                msg = "=============================" + "\n" + \
                    "Name: " + tc['name'] + "\n" + \
                    "Description: " + str(tc['description']) + "\n" + \
                    "Status: " + tc['status'] + "\n"
                print msg
    
    reporter = UTReporter()
    
    def assert_capture(*args, **kwargs):
        '''
        The Decorator defines the override behavior.
        unit test functions decorated with this decorator, will ignore
        the Unittest AssertionError. Instead they will log the test case
        to the UTReporter.
        '''
        def assert_decorator(func):
            def inner(*args, **kwargs):
                tc = {}
                tc['name'] = func.__name__
                tc['description'] = func.__doc__
                try:
                    func(*args, **kwargs)
                    tc['status'] = 'pass'
                except AssertionError:
                    tc['status'] = 'fail'
                reporter.add_testcase(tc)
            return inner
        return assert_decorator
    
    
    
    class DecorateUt(unittest.TestCase):
    
        @assert_capture()
        def test_basic(self):
            x = 5
            self.assertEqual(x, 4)
    
        @assert_capture()
        def test_basic_2(self):
            x = 4
            self.assertEqual(x, 4)
    
    def main():
        #unittest.main()
        suite = unittest.TestLoader().loadTestsFromTestCase(DecorateUt)
        unittest.TextTestRunner(verbosity=2).run(suite)
    
        reporter.display_report()
    
    
    if __name__ == '__main__':
        main()
    

    Output from console:

    (awsenv)$ ./decorators.py 
    init called
    test_basic (__main__.DecorateUt) ... ok
    test_basic_2 (__main__.DecorateUt) ... ok
    
    ----------------------------------------------------------------------
    Ran 2 tests in 0.000s
    
    OK
    =============================
    Name: test_basic
    Description: None
    Status: fail
    
    =============================
    Name: test_basic_2
    Description: None
    Status: pass
    

提交回复
热议问题