一、单元测试框架unittest简介:

  • 单元测试:指的是在软件开发当中,对程序的最小单元(函数、方法)进行测试的过程;
  • unittest不仅可以用于单元测试,还可以用于自动化测试用例的开发和执行。组织执行自动化测试用例。并且提供一些丰富的断言方法,判断用例是否通过,最终能够生成测试报告;
  • unittest:更简单,容易上手;pytest:市场份额会更多;一般情况下:能用pytest尽量用pytest,如果团队 的编码能力欠缺的情况下可以选择unittest,web自动化选择unittest,接口自动化选择pytest。
  • unittest是Python自带的一个单元测试框架,unittest又被称为PyUnit,是由Java的JUnit衍生而来,基本结构是类似的。对于单元测试,需要设置预先条件,对比预期结果和实际结果。
  • 由于unittest是Python自带的标准模块,所以不需要单独再去安装。引入包import unittest即可使用。

二、单元测试框架作用

1.测试发现:从多个py文件中收集并且加载测试用例;
2.测试执行:将测试用例按照一定的顺序和条件去执行并且生成结果
3.测试判断:通过断言去判断结果是否正确;
4.测试报告:统计测试进度,通过率,生成报告;

三、基本概念

1.核心概念

  • TestCase测试用例:
  • TestSuite测试套件:整理测试用例,形成一个集合
  • TestFixtrue测试固件:
  • TestLoader测试加载器:加载测试用例套件或者测试用例
  • TestRunner测试运行器:运行测试用例

2.unittest.TestCase:TestCase类,所有测试用例类继承的基本类

class TestDemo(unittest.TestCase)

3.setupclass():必须使用@classmethod装饰器,所有test运行前执行一次;

import unittest

class TestDemo(unittest.TestCase):
    
    @classmethod
    def setupClass(cls):
        print("hello world")

4.tearDownClass():必须使用@classmethod装饰器,所有test运行完后执行一次;

import unittest

class TestDemo(unittest.TestCase):
    
    @classmethod
    def tearDownClass(cls):
        print("tearDownClass")

5.setup():每个测试方法运行前执行;

import unittest

class TestDemo(unittest.TestCase):
    def setUp(self):
        print("setUp")

6.teardown():每个测试方法运行完后执行;

import unittest

class TestDemo(unittest.TestCase):
    def tearDown(self):
        print("tearDown")

7.每个测试方法均以test开头,否则是不被unittest识别的;

def test_case1(self):
    print('test_case1')

8、unittest.main():将一个单元测试模块变为可直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中以test命名开头的测试方法,并自动执行他们。

执行方法的默认顺序是:根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以以A开头的测试用例方法会优先执行,以a开头会后执行。

9.unittest.TestSuite():创建测试套件。

  • addTest()/addTests()方法是将测试用例添加到测试套件中。
    例如:将test_Demo1模块下的TestDemo1类下的test_case1测试用例添加到测试套件中
suite = unittest.TestSuite()
suite.addTest(test_Demo1.TestDemo1('test_case1'))

10.unittest.TestLoader():根据不同的条件加载测试用例,其中有几个方法:

unittest.TestLoader().loadTestsFromName()
unittest.TestLoader().loadTestsFromNames()
unittest.TestLoader().loadTestsFromTestCase()
unittest.TestLoader().loadTestsFromModule()
unittest.TestLoader().discover()

加载一个目录下所有的测试用例:通过测试加载器:加载测试用例套件或者测试用例

import unittest

if __name__ == '__main__':
    # discover发现
    suite = unittest.defaultTestLoader.discover("./public", pattern='test_*.py')  # 在punlic目录下寻找test_开头的py文件
    unittest.main(defaultTest="suite")

例如:将test_case包下的test_Demo1模块下的TestDemo1类下的test_case1测试用例添加到测试套件中:

suite = unittest.TestSuite()
suite.addTests(unittest.TestLoader().loadTestsFromName('test_case.test_Demo1.TestDemo1.test_case1'))

11.unittest.defaultTestLoader():通过该类下面的discover()方法可自动根据测试目录test_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件中。

discover=unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')

12.unittest.TextTextRunner():通过该类下面的run()方法来运行suite所组装的测试用例,入参为suite测试套件。

suite = unittest.TestSuite()
suite.addTest(TestDemo('test_case1'))
runner = unittest.TextTestRunner()
runner.run(suite)

三、基本示例

  • 1.创建TestDemo类,并继承unittest.TestCase;创建setUpClass、tearDownClass、setUp、tearDown;之后创建多个以test开头的测试方法,每个这样的方法在load的时候便会生成一个TestCase实例,如TestDemo类中有3个test_xxx方法,最后在load到suite中便有3个测试用例。
import unittest

# 定义测试类,父类为unittest.TestCase
class TestDemo(unittest.TestCase):

    #必须使用@classmethod装饰器,所有test运行前执行一次
    @classmethod
    def setUpClass(cls) -> None:
        print("setUpClass")

    # 必须使用@classmethod装饰器,所有test运行完后执行一次
    @classmethod
    def tearDownClass(cls) -> None:
        print("tearDownClass")

    # 每个测试方法运行前执行
    def setUp(self) -> None:
        print("setUp")

    # 每个测试方法运行后执行
    def tearDown(self) -> None:
        print("teardown")

    # 所有的测试方法都要以test为开头
    def test_01(self):
        print("test01")

    def test_02(self):
        print("test02")

    def test_03(self):
        print("test03")


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

执行结果为

pytest框架模块级别和函数级别与类级别和方法级别的区别 pytest与unittest框架原理_测试方法

  • 2、执行test_Demo.py文件,运行结果:
    setUpClass()最先执行;
    tearDownClass()最后执行;
    setup()每个测试方法运行前执行;
    teardown()每个测试方法运行完后执行;
    3个测试方法(test_case1、test_case2、test_case3)。
    最后打印出的3个点为3个测试方法执行结果标识:
    成功是 .失败是 F出错是 E跳过是 S
  • 3.在unittest.main()中加verbosity参数可以控制输出报告的详细程度,默认是1。
    verbosity=0 是简单报告;
    verbosity=1 是一般报告;
    verbosity=2 是详细报告。

    将test_Demo.py文件里的unittest.main()修改为unittest.main(verbosity=2),再次执行脚本。
    运行结果:执行后输出的详细报告信息。