📜  单元测试框架-API

📅  最后修改于: 2020-12-03 05:27:25             🧑  作者: Mango


本章讨论unittest模块中定义的类和方法。此模块中有五个主要类。

TestCase类

此类的对象表示最小的可测试单元。它包含测试例程,并提供钩子以准备每个例程并在之后进行清理。

在TestCase类中定义了以下方法-

Sr.No. Method & Description
1

setUp()

Method called to prepare the test fixture. This is called immediately before calling the test method

2

tearDown()

Method called immediately after the test method has been called and the result recorded. This is called even if the test method raised an exception,

3

setUpClass()

A class method called before tests in an individual class run.

4

tearDownClass()

A class method called after tests in an individual class have run.

5

run(result = None)

Run the test, collecting the result into the test result object passed as result.

6

skipTest(reason)

Calling this during a test method or setUp() skips the current test.

7

debug()

Run the test without collecting the result.

8

shortDescription()

Returns a one-line description of the test.

治具

在TestCase类中可以编写许多测试。这些测试方法可能需要数据库连接,临时文件或其他资源进行初始化。这些称为固定装置。 TestCase包括一个特殊的挂钩,用于配置和清理测试所需的任何固定装置。要配置灯具,请覆盖setUp()。要清理,请重写tearDown()。

在下面的示例中,在TestCase类中编写了两个测试。他们测试两个值的加法和减法结果。 setup()方法基于每个测试的shortDescription()初始化参数。 teardown()方法将在每次测试结束时执行。

import unittest

class simpleTest2(unittest.TestCase):
   def setUp(self):
      self.a = 10
      self.b = 20
      name = self.shortDescription()
      if name == "Add":
         self.a = 10
         self.b = 20
         print name, self.a, self.b
      if name == "sub":
         self.a = 50
         self.b = 60
         print name, self.a, self.b
   def tearDown(self):
      print '\nend of test',self.shortDescription()

   def testadd(self):
      """Add"""
      result = self.a+self.b
      self.assertTrue(result == 100)
   def testsub(self):
      """sub"""
      result = self.a-self.b
      self.assertTrue(result == -10)
      
if __name__ == '__main__':
   unittest.main()

从命令行运行以上代码。它给出以下输出-

C:\Python27>python test2.py
Add 10 20
F
end of test Add
sub 50 60
end of test sub
.
================================================================
FAIL: testadd (__main__.simpleTest2)
Add
----------------------------------------------------------------------
Traceback (most recent call last):
   File "test2.py", line 21, in testadd
      self.assertTrue(result == 100)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 2 tests in 0.015s

FAILED (failures = 1)

类治具

TestCase类具有setUpClass()方法,可以重写该方法以在执行TestCase类内的各个测试之前执行。同样,在类中进行所有测试之后,将执行tearDownClass()方法。这两种方法都是类方法。因此,必须使用@classmethod指令修饰它们。

以下示例演示了这些类方法的用法-

import unittest

class TestFixtures(unittest.TestCase):

   @classmethod
   def setUpClass(cls):
      print 'called once before any tests in class'

   @classmethod
   def tearDownClass(cls):
      print '\ncalled once after all tests in class'

   def setUp(self):
      self.a = 10
      self.b = 20
      name = self.shortDescription()
      print '\n',name
   def tearDown(self):
      print '\nend of test',self.shortDescription()

   def test1(self):
      """One"""
      result = self.a+self.b
      self.assertTrue(True)
   def test2(self):
      """Two"""
      result = self.a-self.b
      self.assertTrue(False)
      
if __name__ == '__main__':
unittest.main()

TestSuite类

Python的测试框架提供了一种有用的机制,通过该机制,可以根据测试用例的测试功能将它们组合在一起。该机制由unittest模块中的TestSuite类提供。

创建和运行测试套件涉及以下步骤。

步骤1-创建一个TestSuite类的实例。

suite = unittest.TestSuite()

步骤2-在套件的TestCase类内添加测试。

suite.addTest(testcase class)

步骤3-您也可以使用makeSuite()方法从类中添加测试

suite = unittest.makeSuite(test case class)

步骤4-单个测试也可以添加到套件中。

suite.addTest(testcaseclass(""testmethod")

步骤5-创建TestTestRunner类的对象。

runner = unittest.TextTestRunner()

第6步-调用run()方法以运行套件中的所有测试

runner.run (suite)

在TestSuite类中定义了以下方法-

Sr.No. Method & Description
1

addTest()

Adds a test method in the test suite.

2

addTests()

Adds tests from multiple TestCase classes.

3

run()

Runs the tests associated with this suite, collecting the result into the test result object

4

debug()

Runs the tests associated with this suite without collecting the result.

5

countTestCases()

Returns the number of tests represented by this test object

以下示例显示如何使用TestSuite类-

import unittest
class suiteTest(unittest.TestCase):
   def setUp(self):
      self.a = 10
      self.b = 20
      
   def testadd(self):
      """Add"""
      result = self.a+self.b
      self.assertTrue(result == 100)
   def testsub(self):
      """sub"""
      result = self.a-self.b
      self.assertTrue(result == -10)
      
def suite():
   suite = unittest.TestSuite()
##   suite.addTest (simpleTest3("testadd"))
##   suite.addTest (simpleTest3("testsub"))
   suite.addTest(unittest.makeSuite(simpleTest3))
   return suite
   
if __name__ == '__main__':
   runner = unittest.TextTestRunner()
   test_suite = suite()
   runner.run (test_suite)

您可以通过取消注释具有makeSuite()方法的行和注释语句来试验addTest()方法。

TestLoader类别

unittest软件包具有TestLoader类,该类用于从类和模块创建测试套件。默认情况下,在调用unittest.main(0方法时,会自动创建unittest.defaultTestLoader实例。但是,显式实例可以启用某些属性的自定义。

在下面的代码中,使用TestLoader对象将两个类的测试收集到一个List中。

import unittest
testList = [Test1, Test2]
testLoad = unittest.TestLoader()

TestList = []
for testCase in testList:
   testSuite = testLoad.loadTestsFromTestCase(testCase)
   TestList.append(testSuite)
   
newSuite = unittest.TestSuite(TestList)
runner = unittest.TextTestRunner()
runner.run(newSuite)

下表显示了TestLoader类中的方法列表-

Sr.No Method & Description
1

loadTestsFromTestCase()

Return a suite of all tests cases contained in a TestCase class

2

loadTestsFromModule()

Return a suite of all tests cases contained in the given module.

3

loadTestsFromName()

Return a suite of all tests cases given a string specifier.

4

discover()

Find all the test modules by recursing into subdirectories from the specified start directory, and return a TestSuite object

TestResult类

此类用于编译有关成功测试和失败测试的信息。 TestResult对象存储一组测试的结果。 TestResult实例由TestRunner.run()方法返回。

TestResult实例具有以下属性-

Sr.No. Attribute & Description
1

Errors

A list containing 2-tuples of TestCase instances and strings holding formatted tracebacks. Each tuple represents a test which raised an unexpected exception.

2

Failures

A list containing 2-tuples of TestCase instances and strings holding formatted tracebacks. Each tuple represents a test where a failure was explicitly signalled using the TestCase.assert*() methods.

3

Skipped

A list containing 2-tuples of TestCase instances and strings holding the reason for skipping the test.

4

wasSuccessful()

Return True if all tests run so far have passed, otherwise returns False.

5

stop()

This method can be called to signal that the set of tests being run should be aborted.

6

startTestRun()

Called once before any tests are executed.

7

stopTestRun()

Called once after all tests are executed.

8

testsRun

The total number of tests run so far.

9

Buffer

If set to true, sys.stdout and sys.stderr will be buffered in between startTest() and stopTest() being called.

以下代码执行测试套件-

if __name__ == '__main__':
   runner = unittest.TextTestRunner()
   test_suite = suite()
   result = runner.run (test_suite)
   
   print "---- START OF TEST RESULTS"
   print result

   print "result::errors"
   print result.errors

   print "result::failures"
   print result.failures

   print "result::skipped"
   print result.skipped

   print "result::successful"
   print result.wasSuccessful()
   
   print "result::test-run"
   print result.testsRun
   print "---- END OF TEST RESULTS"

执行后的代码显示以下输出-

---- START OF TEST RESULTS

result::errors
[]
result::failures
[(<__main__.suitetest testmethod="testadd">, 'Traceback (most recent call last):\n
   File "test3.py", line 10, in testadd\n 
   self.assertTrue(result == 100)\nAssert
   ionError: False is not true\n')]
result::skipped
[]
result::successful
False
result::test-run
2
---- END OF TEST RESULTS