python之unittest单元测试框架的常用的断言方式

1. 单元测试简介

单元测试是软件开发中的一种测试方法。它是指对程序模块(软件设计的最小单位)进行测试的过程。使用单元测试的好处是可以在程序发布之前发现潜在的问题,从而保证程序的质量。在 Python 中,单元测试框架是 unittest。unittest 框架提供了很多常用的测试方法,我们可以使用它们编写测试用例并执行测试,以验证程序是否按照我们预期的方式执行。

2. unittest 单元测试框架

unittest 是 Python 官方提供的一个单元测试框架,它支持自动化测试、模块测试和集成测试。unittest 框架提供了很多常用的测试方法,我们可以使用它们编写测试用例并执行测试,以验证程序是否按照我们预期的方式执行。unittest 框架包含以下几个组成部分:

2.1 Test Case 类

Test Case 类是 unittest 框架的一个重要组成部分。它负责测试用例的编写和执行,每个测试用例都应该继承自 TestCase 类。在 TestCase 类中,我们可以定义多个测试方法,对应着被测程序的不同功能,每个测试方法应该包含多条测试语句,以验证被测程序是否按照我们预期的方式执行。例如:

import unittest

class MyTest(unittest.TestCase):

def test_add(self):

self.assertEqual(1 + 1, 2)

self.assertEqual(2 + 2, 4)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_add,用于验证加法运算是否正确执行。在 test_add 方法中,我们使用断言方法 self.assertEqual 来进行验证,确保程序输出的结果与我们预期的结果相同。

2.2 Test Suite 类

Test Suite 类代表了整个测试套件,它可以包含多个测试用例。Test Suite 类提供了一些方法来管理测试用例,比如添加测试用例、删除测试用例、运行测试用例等。例如:

import unittest

class MyTest(unittest.TestCase):

def test_add(self):

self.assertEqual(1 + 1, 2)

self.assertEqual(2 + 2, 4)

class MyTestSuite(unittest.TestSuite):

def __init__(self):

super().__init__()

self.addTest(MyTest('test_add'))

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = MyTestSuite()

runner.run(suite)

在上述代码中,我们定义了一个 MyTestSuite 类,继承自 unittest.TestSuite 类。该类包含了一个 MyTest 测试用例,我们使用 addTest 方法将其添加到测试套件中。最后,我们使用 TextTestRunner 类来运行测试套件。

2.3 Test Loader 类

Test Loader 类是负责加载测试用例并形成测试套件的对象。它提供了一些方法来管理测试用例文件,比如查找测试用例、装载测试用例等。在 unittest 框架中,默认使用的是 unittest.defaultTestLoader 类来装载测试用例,但是我们也可以自定义 Test Loader 类。例如:

import unittest

class MyTest(unittest.TestCase):

def test_add(self):

self.assertEqual(1 + 1, 2)

self.assertEqual(2 + 2, 4)

class MyTestLoader(unittest.TestLoader):

def loadTestsFromTestCase(self, testCaseClass):

suite = super().loadTestsFromTestCase(testCaseClass)

suite.addTest(testCaseClass('test_add'))

return suite

if __name__ == '__main__':

runner = unittest.TextTestRunner()

loader = MyTestLoader()

suite = loader.loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 MyTestLoader 类,继承自 unittest.TestLoader 类。该类在 loadTestsFromTestCase 方法中,调用了父类方法获取测试套件,并使用 addTest 方法将 MyTest 测试用例添加到测试套件中。最后我们使用 TextTestRunner 类来运行测试套件。

2.4 Test Result 类

Test Result 类是记录测试结果的类,它负责跟踪测试过程中的错误信息、失败信息、通过信息等,并将这些信息输出到控制台或者文件中。Test Result 类包含一个属性 errors,用于记录测试过程中出现的错误信息,还包含一个属性 failures,用于记录测试过程中出现的失败信息。例如:

import unittest

class MyTest(unittest.TestCase):

def test_add(self):

self.assertEqual(1 + 1, 2)

self.assertEqual(2 + 2, 5)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

result = runner.run(suite)

print(result.errors)

print(result.failures)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_add,用于验证加法运算是否正确执行。在 test_add 方法中,我们故意将 2 + 2 的结果写成了 5,从而让它出现错误。最后,我们使用 TextTestRunner 类来运行测试套件,并使用 TestResult 类来记录测试结果,输出到控制台中。

3. 常用的断言方式

在编写测试用例时,我们需要使用断言来判断程序执行的结果是否正确。unittest 框架提供了很多常用的断言方式,下面我们将逐一介绍。

3.1 assertEqual(a, b, msg=None)

assertEqual 方法用于判断两个对象是否相等。如果不相等,则会抛出 AssertionError 异常,并输出指定的错误信息。例如:

import unittest

class MyTest(unittest.TestCase):

def test_equal(self):

self.assertEqual(1 + 1, 2)

self.assertEqual(2 + 2, 5)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_equal,用于验证两个加法运算的结果是否正确。在 test_equal 方法中,我们分别使用 assertEqual 方法来判断 1+1 和 2+2 的结果是否等于预期值。由于 2+2 的结果不等于预期值,因此该测试用例会抛出 AssertionError 异常,并输出错误信息。

3.2 assertNotEqual(a, b, msg=None)

assertNotEqual 方法用于判断两个对象是否不相等。如果相等,则会抛出 AssertionError 异常,并输出指定的错误信息。例如:

import unittest

class MyTest(unittest.TestCase):

def test_not_equal(self):

self.assertNotEqual(1 + 1, 3)

self.assertNotEqual(2 + 2, 5)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_not_equal,用于验证两个加法运算的结果是否不等于预期值。在 test_not_equal 方法中,我们分别使用 assertNotEqual 方法来判断 1+1 和 2+2 的结果是否不等于预期值。

3.3 assertTrue(expr, msg=None)

assertTrue 方法用于判断一个表达式是否为真。如果表达式为假,则会抛出 AssertionError 异常,并输出指定的错误信息。例如:

import unittest

class MyTest(unittest.TestCase):

def test_true(self):

self.assertTrue(1 < 2)

self.assertTrue(2 > 3)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_true,用于验证两个比较表达式的结果是否为真。在 test_true 方法中,我们分别使用 assertTrue 方法来判断 1<2 和 2>3 两个表达式是否为真。

3.4 assertFalse(expr, msg=None)

assertFalse 方法用于判断一个表达式是否为假。如果表达式为真,则会抛出 AssertionError 异常,并输出指定的错误信息。例如:

import unittest

class MyTest(unittest.TestCase):

def test_false(self):

self.assertFalse(1 > 2)

self.assertFalse(2 < 1)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_false,用于验证两个比较表达式的结果是否为假。在 test_false 方法中,我们分别使用 assertFalse 方法来判断 1>2 和 2<1 两个表达式是否为假。

3.5 assertIs(a, b, msg=None)

assertIs 方法用于判断两个对象的身份是否相同,即它们是否是同一个对象。如果不是同一个对象,则会抛出 AssertionError 异常,并输出指定的错误信息。例如:

import unittest

class Demo():

pass

class MyTest(unittest.TestCase):

def test_is(self):

x = Demo()

y = x

z = Demo()

self.assertIs(x, y)

self.assertIsNot(x, z)

self.assertIsNot(y, z)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_is,用于验证三个 Demo 类对象的身份是否相同。其中,x 和 y 是同一个对象,而 z 是不同的对象。在 test_is 方法中,我们分别使用 assertIs、assertIsNot 方法来判断三个对象是否是同一个对象。

3.6 assertIsNot(a, b, msg=None)

assertIsNot 方法用于判断两个对象的身份是否不同,即它们是否不是同一个对象。如果是同一个对象,则会抛出 AssertionError 异常,并输出指定的错误信息。例如:

import unittest

class Demo():

pass

class MyTest(unittest.TestCase):

def test_is_not(self):

x = Demo()

y = Demo()

self.assertIsNot(x, y)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 Demo 类和一个 MyTest 类,其中 Demo 类是一个空类,MyTest 类是一个测试类,包含一个测试方法 test_is_not。在 test_is_not 方法中,我们创建了两个 Demo 类对象 x 和 y,并使用 assertIsNot 方法来判断它们是否是同一个对象。由于它们不是同一个对象,因此该测试用例会执行通过。

3.7 assertIn(a, b, msg=None)

assertIn 方法用于判断一个值是否包含在一个可迭代对象中。如果不包含,则会抛出 AssertionError 异常,并输出指定的错误信息。例如:

import unittest

class MyTest(unittest.TestCase):

def test_in(self):

a = [1, 2, 3, 4]

b = [5, 6, 7, 8]

self.assertIn(2, a)

self.assertIn(4, a)

self.assertNotIn(5, a)

self.assertIn(5, b)

self.assertNotIn(2, b)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_in,用于验证一个值是否包含在一个列表中。在 test_in 方法中,我们分别使用 assertIn、assertNotIn 方法来判断一个值是否包含在列表中。

3.8 assertNotIn(a, b, msg=None)

assertNotIn 方法用于判断一个值是否不包含在一个可迭代对象中。如果包含,则会抛出 AssertionError 异常,并输出指定的错误信息。例如:

import unittest

class MyTest(unittest.TestCase):

def test_not_in(self):

a = [1, 2, 3, 4]

b = [5, 6, 7, 8]

self.assertIn(2, a)

self.assertIn(4, a)

self.assertNotIn(5, a)

self.assertIn(5, b)

self.assertNotIn(2, b)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_not_in,用于验证一个值是否不包含在一个列表中。在 test_not_in 方法中,我们分别使用 assertNotIn、assertIn 方法来判断一个值是否不包含在列表中。

3.9 assertGreater(a, b, msg=None)

assertGreater 方法用于判断一个值是否大于另一个值。如果不大于,则会抛出 AssertionError 异常,并输出指定的错误信息。例如:

import unittest

class MyTest(unittest.TestCase):

def test_greater(self):

x = 5

y = 3

self.assertGreater(x, y)

self.assertGreaterEqual(x, y)

self.assertLess(y, x)

self.assertLessEqual(y, x)

if __name__ == '__main__':

runner = unittest.TextTestRunner()

suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)

runner.run(suite)

在上述代码中,我们定义了一个 MyTest 类,继承自 unittest.TestCase 类。该类包含一个测试方法 test_greater,用于验证一个值是否大于另一个值。在 test_greater 方法中,我们分别使用 assertGreater、assertGreaterEqual

后端开发标签