如何在Python Unittest中使用TearDownClass与TestResult.wasSuccessful()

1 投票
2 回答
8129 浏览
提问于 2025-04-19 10:51

我想要调用 setUpClasstearDownClass,这样 setupteardown 就只会在每个测试开始和结束时执行一次。然而,当我调用 tearDownClass 的时候,总是出错。我只想记录一个测试结果,如果两个测试都通过就显示为通过(PASS),如果两个测试都失败就显示为失败(FAIL)。如果我只调用 setupteardown,那一切都正常:

调用 setUpClasstearDownClass 的代码:

#!/usr/bin/python

import datetime
import itertools
import logging
import os
import sys
import time
import unittest

LOGFILE = 'logfile.txt'

class MyTest(unittest.TestCase):

    global testResult
    testResult = None

    @classmethod
    def setUpClass(self):

        ## test result for DB Entry:
        self.dbresult_dict = {
             'SCRIPT'       : 'MyTest.py',
             'RESULT'      : testResult,
        }

    def test1(self):

       expected_number = 10
       actual_number = 10

       self.assertEqual(expected_number, actual_number) 

   def test2(self):

       expected = True
       actual = True

       self.assertEqual(expected, actual)


   def run(self, result=None):
       self.testResult = result
       unittest.TestCase.run(self, result)

   @classmethod
   def tearDownClass(self):
       ok = self.testResult.wasSuccessful()
       errors = self.testResult.errors
       failures = self.testResult.failures
       if ok:
           self.dbresult_dict['RESULT'] = 'Pass'
       else:
           logging.info(' %d errors and %d failures',
                 len(errors), len(failures))
           self.dbresult_dict['RESULT'] = 'Fail'

if __name__ == '__main__':
   logger = logging.getLogger()
   logger.addHandler(logging.FileHandler(LOGFILE, mode='a'))
   stderr_file = open(LOGFILE, 'a')

   runner = unittest.TextTestRunner(verbosity=2, stream=stderr_file, descriptions=True)
   itersuite = unittest.TestLoader().loadTestsFromTestCase(MyTest)
   runner.run(itersuite)
   sys.exit()
   unittest.main(module=itersuite, exit=True)

stderr_file.close()

错误信息:

test1 (__main__.MyTest) ... ok
test2 (__main__.MyTest) ... ok
ERROR
===================================================================
ERROR: tearDownClass (__main__.MyTest)
-------------------------------------------------------------------
Traceback (most recent call last):
   File "testTearDownClass.py", line 47, in tearDownClass
    ok = self.testResult.wasSuccessful()
AttributeError: type object 'MyTest' has no attribute 'testResult'
----------------------------------------------------------------------
Ran 2 tests in 0.006s
FAILED (errors=1)

2 个回答

-4

tearDownClass(self) 改成 tearDownClass(cls),把 setUpClass(self) 改成 setUpClass(cls)

0

就像@Marcin已经指出的,你在使用Unittest框架的方式不太对。

  1. 要检查测试是否成功,你需要把给定的值和预期的值进行对比,就像你已经做的那样:assertEqual(given, expected)。Unittest会自动收集失败的测试总结,你不需要手动去做这个。
  2. 如果你想检查两个测试要么一起成功,要么一起失败,它们应该放在一个测试里,也许可以作为一个额外的测试,如果你还需要单独检查这些测试的话。测试本身应该尽量保持无状态,也就是说,不应该保存和加载任何东西。
  3. 当你说想要每个测试都运行一次SetUp和TearDown时,你是指每个测试方法运行一次,还是每次测试运行时?如果你的类里有多个测试方法,这两者是不同的:
  • setUp() 会在每个测试方法之前被调用
  • tearDown() 会在每个测试方法之后被调用
  • setUpClass() 会在每个类中被调用一次(在这个类的第一个测试方法之前)
  • tearDownClass() 会在每个类中被调用一次(在这个类的最后一个测试方法之后)

这里是官方文档

这里是一个相关的回答

撰写回答