一、摘要

本章笔者将详细介绍组织测试代码的相关内容,所用的测试例子会是冒泡排序,笔者在从业这么久之后回想很多面试都要问冒泡排序,虽然不知道为什么要问这个,但还是希望大家掌握,它与自动化测试关系不大属于python的基础范畴

在上一篇内容中我们展示了一个小例子,在代码的前两行是如下内容

import unittest
class TestStringMethods(unittest.TestCase): 

它的意义何在呢? import unittest 导入unittest模块,使得我们可以使用它,class TestStringMethods(unittest.TestCase): 新创建的测试类继承了unittest.TestCase,使得我们可以是使用TestCase里的特性

那么它有哪些主要特性呢?

 1、测试用例,当我们的测试类继承了unittest.TestCase,若以“def test_xxx(self):”这样的命名方式(test开头)在测试类中定义函数时,它就会被unittest认为是一条测试方法;然而就像我们做手动测试用例的时候,总有一些原则在,那么在写自动化测试用例时有哪些主要的原则呢?

  • 每一个测试用例必须是完全独立的,从而能够单独执行,也可以组团执行
  • 每一个测试用例必须有断言,从而在测试失败的情况下断言异常和一条解释性的语句(AssertionError)将会抛出,此时unittest将会将这条用例标识为失败,其他的异常类型将会被认为是错误(error)
  • 在设计测试用例时要尽可能考虑后续维护的问题,我们要尽可能的减少修改测试代码,从而能够满足快速的迭代测试

2、setUp():这个函数也继承自unittest.TestCase,它的作用是用来完成每一个测试方法执行前的准备工作,如果setUp()方法执行的时候出现异常,那么unittest框架认为测试出现了错误,测试方法是不会被执行的

3、tearDown(): 同样继承自unittest.TestCase,它的作用是每一个测试方法执行完后的清理工作,如果setUp()执行成功,那么测试方法执行成功还是失败,tearDown()方法都会被执行

4、setUpClass(): 同样继承自unittest.TestCase,它的作用是完成在所有测试方法执行前(包括setUp()),单元测试的前期准备工作,必须用@classmethod修饰,整个测试类只执行一次

5、tearDownClass(): 同样继承自unittest.TestCase,它的作用是完成在所有测试方法执行后(包括tearDown()),单元测试的清理工作,必须用@classmethod修饰,整个测试类只执行一次

6、还有一种特例,最简单的测试用例只需要通过覆盖runTest()方法来执行自定义的测试代码,我们称之为静态方法,测试方法名不能重复,也意味着测试类中只能有一个runTest()方法,很显然这样的方式会导致很多冗余代码

7、使用了1到5测试特性构建测试用例的,我们称之为动态方法

二、实例代码

下边将用实例代码详细展示如上概念,待测代码如下

class BubbleSort(object):
    def __init__(self, mylist):
        self.myList = mylist
        self.length = len(mylist)

    def ascending_order(self):
        for i in range(self.length-1):
            for j in range(self.length-1-i):
                if self.myList[j] > self.myList[j + 1]:
                    self.myList[j], self.myList[j+1] = self.myList[j+1], self.myList[j]
        return self.myList

    def descending_order(self):
        for i in range(self.length-1):
            for j in range(self.length-1-i):
                if self.myList[j] < self.myList[j + 1]:
                    self.myList[j], self.myList[j+1] = self.myList[j+1], self.myList[j]
        return self.myList

测试代码如下:

import unittest
from Util.BubbleSort import BubbleSort


class TestBubbleSort(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("execute setUpClass\n")

    @classmethod
    def tearDownClass(cls):
        print("execute tearDownClass\n")

    def setUp(self):
        self.list1 = [2, 10, 25, 30, 45, 100, 325]
        self.list3 = [325, 10, 25, 45, 30, 100, 2]
        self.list4 = [11, 3, 41, 101, 327, 26, 46]
        self.list2 = [327, 101, 46, 41, 26, 11, 3]

    def tearDown(self):
        print("execute tearDown\n")

    def test_descending_order(self):
        bls = BubbleSort(self.list4)
        self.list5 = bls.descending_order()
        print(self.list5)
        self.assertEqual(self.list5, self.list2)

    def test_ascending_order(self):
        bls = BubbleSort(self.list3)
        self.list6 = bls.ascending_order()
        print(self.list6)
        self.assertEqual(self.list6, self.list1)


if __name__ == '__main__':
    unittest.main()

执行结果应该是

..
execute setUpClass
----------------------------------------------------------------------

Ran 2 tests in 0.001s

[2, 10, 25, 30, 45, 100, 325]
OK
execute tearDown

[327, 101, 46, 41, 26, 11, 3]
execute tearDown

execute tearDownClass


Process finished with exit code 0

三、代码解析

从测试用例的设计和运行结果结合看,意义印证了摘要当中提及的TestCase的特性

12-24 09:55