zoukankan      html  css  js  c++  java
  • unittest单元测试框架教程6-unittest.TestCase类详解

    unittest.TestCase(methodName ='runTest' )

    TestCase类的实例,作为编写的测试类的基类,具体测试由具体的子类(就是我们写的测试类)实现。此类实现测试运行程序所需的接口,以使其能够驱动测试,以及测试代码可用于检查和报告各种失败的方法。

    每个TestCase实例(就是我们写的测试类)将运行一个基本方法:我们编写的测试方法TestCase 实例提供了三组方法:一组用于运行测试,另一组由测试实现用于检查条件和报告故障,还有一些查询方法允许收集有关测试本身的信息。

    第一组的方法是:

    setUp()

    在调用测试方法之前立即调用该方法。除了AssertionErrorSkipTest之外,此方法引发的任何异常都将被视为错误而不是测试失败。默认实现不执行任何操作。

    tearDown()

    调用测试方法并记录结果后立即调用的方法。即使测试方法引发了异常,也将调用此方法,因此子类中的实现可能需要特别注意检查内部状态。除了AssertionErrorSkipTest之外,此方法引发的任何异常都将被视为错误(errors)而不是测试失败(Failures)setUp()无论测试方法的结果如何,仅在成功的情况下才调用此方法(wasSuccessful()==True)。默认实现不执行任何操作。

    setUpClass()

    在运行单个类中的测试之前调用的类方法。setUpClass以类作为唯一参数调用,并且必须修饰为classmethod()

    @classmethod
    def setUpClass(cls):
        ...

    tearDownClass()

    与setUpClass原理一致

    run(result = None)

    运行测试,将结果收集到TestResult作为result传递对象中如果省略resultNone,则创建一个临时结果对象(通过调用该defaultTestResult() 方法)并使用它。结果对象返回给run()的调用者。

    通过简单地调用TestCase 实例

    result = TestAdd('test_add1').run()
    result = TestAdd('test_chengfa').run()
    print(result)

    会生成一个测试结果

    <unittest.result.TestResult run=1 errors=0 failures=1>

    skipTest(reason)

    @unittest.skip(reason)

    跳过被此装饰器装饰的测试。 reason 为测试被跳过的原因。

    @unittest.skipIf(conditionreason)

    当 condition 为真时,跳过被装饰的测试。

    @unittest.skipUnless(conditionreason)

    跳过被装饰的测试,除非 condition 为真。

    @unittest.expectedFailure

    把测试标记为预计失败。如果测试不通过,会被认为测试成功;如果测试通过了,则被认为是测试失败。

    exception unittest.SkipTest(reason)

    引发此异常以跳过一个测试。

    通常来说,你可以使用 TestCase.skipTest() 或其中一个跳过测试的装饰器实现跳过测试的功能,而不是直接引发此异常。

    被跳过的测试的 setUp() 和 tearDown() 不会被运行。被跳过的类的 setUpClass() 和 tearDownClass() 不会被运行。被跳过的模组的 setUpModule() 和 tearDownModule() 不会被运行。

        def test_chengfa(self):
            '''测试乘法程序'''
            self.skipTest('暂不测试')
            ...

    加入后运行,就会跳过

    1
    2
    1
    2
    1
    2
    <unittest.runner.TextTestResult run=3 errors=0 failures=0>
    .s.
    ----------------------------------------------------------------------
    Ran 3 tests in 0.041s
    
    OK (skipped=1)

    subTest(msg = None** params)

    可参考unittest单元测试框架教程5-使用subTest进行循环测试

    debug()

    运行测试而不收集结果。这样可以将测试引发的异常传播到调用方,并可以用于支持在调试器下运行测试。

    result = TestAdd('test_add1').debug()
    result = TestAdd('test_chengfa').debug()
    print(result)

    运行后会详细的输出错误信息,便于定位

    1
    2
    Traceback (most recent call last):
      File "D:PycharmProjectsuntitled	estrunner.py", line 13, in <module>
        result = TestAdd('test_chengfa').debug()
      File "C:UsersMZMAppDataLocalProgramsPythonPython37-32libunittestcase.py", line 681, in debug
        getattr(self, self._testMethodName)()
      File "D:PycharmProjectsuntitled	estmath.py", line 53, in test_chengfa
        self.assertEqual(resp['data'], self.a * self.b)
      File "C:UsersMZMAppDataLocalProgramsPythonPython37-32libunittestcase.py", line 852, in assertEqual
        assertion_func(first, second, msg=msg)
      File "C:UsersMZMAppDataLocalProgramsPythonPython37-32libunittestcase.py", line 845, in _baseAssertEqual
        raise self.failureException(msg)
    AssertionError: 3 != 2

    第二组方法提供了一些断言方法来检查并报告故障。

    assertRaises(exceptioncallable* args** kwds)

    测试除法分母为0报异常

    class TestMath(unittest.TestCase):
    def setUp(self):
    pass

    def tearDown(self):
    pass


    def test_chufa(self):
    '''测试乘法程序'''
    self.assertEqual(chufa(0,0), 0)

    E
    ======================================================================
    ERROR: test_chufa (testmath.TestMath)
    测试乘法程序
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    File "D:PycharmProjectsunitest estmath.py", line 87, in test_chufa
    self.assertEqual(chufa(0,0), 0)
    File "D:PycharmProjectsunitest estmath.py", line 74, in chufa
    return a/b
    ZeroDivisionError: division by zero

    ----------------------------------------------------------------------
    Ran 1 test in 0.001s

    加入assertraise断言后不会报错

            with self.assertRaises(ZeroDivisionError):
                self.assertEqual(resp['data'], self.a / self.b)

    assertRaisesRegex(exceptionregexcallable* args** kwds )

    也是一样的操作

    with self.assertRaisesRegex(ZeroDivisionError, 'ok'):
    self.assertEqual(resp['data'], self.a / self.b)

    F
    ======================================================================
    FAIL: test_chufa (testmath.TestMath)
    测试乘法程序
    ----------------------------------------------------------------------
    ZeroDivisionError: division by zero

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File "D:PycharmProjectsunitest estmath.py", line 89, in test_chufa
    self.assertEqual(chufa(0,0), 0)
    AssertionError: "ok" does not match "division by zero"

    ----------------------------------------------------------------------
    Ran 1 test in 0.001s

    FAILED (failures=1)

    with self.assertRaisesRegex(ZeroDivisionError, 'by'):
        self.assertEqual(resp['data'], self.a / self.b)
    1
    0
    <unittest.runner.TextTestResult run=1 errors=0 failures=0>
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.028s
    
    OK

    用于执行更具体检查的方法

     assertAlmostEqual(a, b)

    举个例子self.assertAlmostEqual(1.00000002,1.00000001)第八位不报错,self.assertAlmostEqual(1.0000001,1.0000002)第七位就会报错,因为默认比的是第七位之前

    self.assertAlmostEqual(1.02,1.01,1)不报错self.assertAlmostEqual(1.02,1.01,2)报错,因为默认比的是第二位之前

    place参数表示第n位前都相等,之后无所谓

    assertRegex(textregexmsg = None)

    测试正则表达式搜索是否匹配(或不匹配)text

    assertCountEqual(firstsecondmsg = None)

    测试第一个序列是否包含与第二个相同的元素,而不管它们的顺序如何。否则,将生成一条错误消息,列出序列之间的差异。

    下表总结了自动比较使用的特定类型方法的列表

    最后,TestCase提供以下方法和属性:

    failmsg = None 

    failureException

    此类属性给出了测试方法引发的异常。如果测试框架需要使用专门的异常(可能带有其他信息),则它必须将该异常子类化,以便与框架“公平竞争”。此属性的初始值为 AssertionError

    使用msgNone错误消息无条件地指示测试失败

    代码中加入

            if resp['status'] == 0:
                raise self.failureException(ConnectionError)

    并修改测试程序使其返回0

    F
    ======================================================================
    FAIL: test_chufa (testmath.TestMath)
    测试乘法程序
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    File "D:PycharmProjectsunitest estmath.py", line 89, in test_chufa
    raise self.failureException(ConnectionError)
    AssertionError: <class 'ConnectionError'>

    ----------------------------------------------------------------------
    Ran 1 test in 0.001s

    FAILED (failures=1)

    测试框架可以使用以下方法来收集有关测试的信息:

    countTestCases()

    返回此测试对象表示的测试数量。

    print(TestAdd('test_chengfa').countTestCases())
    loader = unittest.TestLoader()
    suite = loader.loadTestsFromTestCase(TestAdd)
    print(suite.countTestCases())
    suite.addTest(TestAdd('test_chengfa'))
    print(suite.countTestCases())

    1
    4
    5

    id()

    返回标识特定测试用例的字符串。这通常是测试方法的全名,包括模块和类名。

    print(TestAdd('test_chengfa').id())

    返回testmath.TestAdd.test_chengfa

    shortDescription()

    返回测试的描述,或者None没有提供描述。此方法的默认实现返回测试方法docstring的第一行(如果有),或None

    doCleanups()

    tearDown()或在setUp()引发异常之后无条件调用此方法

    如果使setup方法报错

    def setUp(self):
    self.file = open('testtext.txt','w+',encoding='utf-8')
    self.file.write('测试开始')
    self.a = 1/0
    self.b = 2/0

    def tearDown(self):
    print(self.a)
    print(self.b)
    self.file.write('测试结束')
    self.file.close()


    ...

    runner = unittest.TextTestRunner()
    suite = unittest.TestSuite()
    suite.addTest(TestAdd('test_add1'))
    result = runner.run(suite)

    出现错误,且不会运行tearDown

    E
    ======================================================================
    ERROR: test_add1 (testmath.TestAdd)
    测试加法程序
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "D:PycharmProjectsuntitled	estmath.py", line 11, in setUp
        self.a = 1/0
    ZeroDivisionError: division by zero
    
    ----------------------------------------------------------------------
    Ran 1 test in 0.001s
    
    FAILED (errors=1)
    <unittest.runner.TextTestResult run=1 errors=1 failures=0>

    加入doCleanups()后

        def doCleanups(self):
            self.file.write('测试结束')
            self.file.close()

    就会将"测试结束"写入文件了

  • 相关阅读:
    错误:Authentication with old password no longer supported, use 4.1 style passwords.
    百度有钱 邀请码
    [datatables杂记] sAjaxSource 数据源 Search 后 fnInitComplete 不执行。
    uploadify onComplete 不执行?
    VS 2013 简体中文 专业版 下载地址。
    C# 导出图片到Word (通过XML实现)
    使用OutLook发送一封带附件的邮件
    WebBrower使用 Http 代理访问网页
    .net SMTP 发送邮件
    C# 汉字转拼音 方法(汉字的发音不过400多种(不算声调))
  • 原文地址:https://www.cnblogs.com/zerotest/p/13554124.html
Copyright © 2011-2022 走看看