单元测试-Unittest框架实践

文章目录

  • 1.Unittest简介
    • [1.1 自动化测试用例编写步骤](#1.1 自动化测试用例编写步骤)
    • [1.2 相关概念](#1.2 相关概念)
    • [1.3 用例编写规则](#1.3 用例编写规则)
    • [1.4 断言方法](#1.4 断言方法)
  • 2.示例
    • [2.1 业务代码](#2.1 业务代码)
    • [2.2 编写测试用例](#2.2 编写测试用例)
    • [2.3 生成报告](#2.3 生成报告)
      • [2.3.1 方法1](#2.3.1 方法1)
      • [2.3.2 方法2](#2.3.2 方法2)

1.Unittest简介

Unittest是Python自带的单元测试框架,适用于:单元测试、Web自动化、App自动化、接口自动化等测试用例的开发与执行。

1.1 自动化测试用例编写步骤

python 复制代码
1. 初始化	-	用例之前的动作
2. 执行		- 	具体用例逻辑
3. 断言		- 	校验用例执行结果
4. 清理		- 	用例执行后的动作

在unittest中,测试用例的执行顺序是依据ascill码来执行的

在Unittest框架下创建测试用例,步骤如下:
1) 创建test_开头单元测试用例模块。
2) 导入unittest模块。
3) 创建Test开头测试类。继承unittest.TestCase类。
4) 添加setUp()、tearDown()、setUpClass()、tearDownClass() 函数。
5) 创建test_测试方法。
6) 调用unittest.main()方法,该方法会搜索该模块下所有以test开头的测试用例方法并执行。

1.2 相关概念

python 复制代码
概念:
1. test case:测试用例
  ------lass TestLogin(unittest.TestCase):  #继承unittest.TestCase类
2. test suite:测试套件/测试集
3. test loader:测试加载
4. test runner:运行器、执行器
5. fixture:夹具,前置准备和后置清理

1.3 用例编写规则

python 复制代码
1. .py模块命名规则:test_
2. 用例类名命名规则:Test
3. 方法命名规则:def test_

1.4 断言方法

shell 复制代码
注意:
如果断言成功则该条测试用例通过;
断言失败则该条测试用例执行失败,且会抛出AssertionError错误;
以下断言方法中,都有一个msg参数,默认为None。如果msg参数有对应的值,则断言失败后该msg的值会作为失败信息返回,
如 assertEqual(a, b, msg="a与b不相等!") 。
断言方法 含义
assertEqual(a, b) 判断 a == b
assertNotEqual(a, b) 判断 a != b
assertTrue(x) 判断 bool(x) is True
assertFalse(x) 判断 bool(x) is False
assertIs(a, b) 判断 a is b
assertIsNot(a, b) 判断 a is not b
assertIsNone(x) 判断 x is None
assertIsNotNone(x) 判断 x is not None
assertIn(a, b) 判断 a in b
assertNotIn(a, b) 判断 a not in b
assertIsInstance(a, b) 判断 isinstance(a, b)
assertNotIsInstance(a, b) 判断 not isinstance(a, b)

2.示例

2.1 业务代码

创建业务代码:calculator.py

python 复制代码
# -*- coding: utf-8 -*-
"""
Author: zhangsan
date:   2024/12/18 14:05
Description:    

"""


class Math():
    def __init__(self, a, b):
        self.a = int(a)
        self.b = int(b)

    def sum(self):
        # 求和
        return self.a + self.b

    def sub(self):
        # 求差
        return self.a - self.b

2.2 编写测试用例

python 复制代码
# -*- coding: utf-8 -*-
"""
Author: zhangsan
date:   2024/12/18 14:07
Description:    

"""

import unittest
from example_unittest.calculator import Math


class TestSum(unittest.TestCase):
    """测试Math类中的sum方法"""

    # 注意装饰器必须要有
    @classmethod
    def setUpClass(cls):
        # 作用于测试类
        print(f"开始执行测试用例类:{cls.__name__}...")

    @classmethod
    def tearDownClass(cls):
        # 作用于测试类
        print(f"测试用例{cls.__name__}类执行结束。")

    def setUp(self) -> None:
        # 作用于测试方法
        # 每个用例执行前,都会执行一次,用于初始化测试环境
        print(f"开始执行测试用例:{self._testMethodName}...")

    def tearDown(self) -> None:
        # 作用于测试方法
        # 每个用例执行后,都会执行一次,用于清理测试环境
        print(f"测试用例{self._testMethodName}执行结束。")

    def test_sum01(self):
        # 使用正数进行测试
        m = Math(3, 4)
        self.assertEqual(m.sum(), 7)

    def test_sum02(self):
        # 使用负数进行测试
        m = Math(-1, -2)
        self.assertEqual(m.sum(), -3)

    def test_sum03(self):
        # 使用正负数混合进行测试
        m = Math(3, -4)
        self.assertEqual(m.sum(), -1)

    def test_sum04(self):
        # 使用浮点数进行测试
        try:
            m = Math(3.5, 4.6)
        except AssertionError as e:
            print(f"执行用例失败:{e}")
        else:
            self.assertNotEquals(m.sum(), 8.1)

    def test_sum05(self):
        # 使用零进行测试
        m = Math(0, 0)
        self.assertEqual(m.sum(), 0)

    def test_sum06(self):
        # 使用整型和字符串进行测试
        with self.assertRaises(ValueError):
            Math("a", "b")

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

2.3 生成报告

2.3.1 方法1

python 复制代码
# -*- coding: utf-8 -*-
"""
Author: zhangsan
date:   2024/12/18 14:36
Description:    

"""
import unittest
# 导入测试用例模块
from testcase.test_sum import TestSum

# 方法1:
# 第一步:创建TestSuite实例
# suite = unittest.TestSuite()

# 第二步:将测试用例添加至TestSuite
# 方式1,添加单条测试用例
# suite.addTest(TestSum('test_sum01'))  # addTest()里参数格式为:测试类('测试方法')
# suite.addTest(TestSum('test_sum02'))

# 方式2,添加多条测试用例
# suite.addTests([TestSum('test_sum01'), TestSum('test_sum02')])

# 方法2:
# 创建一个加载对象
# loader = unittest.TestLoader()
# suite.addTest(loader.loadTestsFromTestCase(TestSum))

# 方法3:不需要创建unittest.TestSuite()
test_dir = './testcase'
suite = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')

# 第三步:创建TextTestRunner实例
# 创建TextTestRunner实例
# runner = unittest.TextTestRunner()
# 使用run()方法运行测试套件(即运行测试套件中的所有用例)
# runner.run(suite)


# 生成测试报告:HTMLTestRunner无法安装,不能使用
# import HTMLTestRunner
# with open('./report/report.html', 'wb') as f:
#     runner = HTMLTestRunner.HTMLTestRunner(stream=f, title="测试报告", description="测试描述")
#     runner.run(suite)

#导入BeautifulReport模块,这个模块也是生成报告的模块,但是比HTMLTestRunner模板好看
# pip3 install BeautifulReport
# from BeautifulReport import BeautifulReport as bf
#
# run = bf(suite) #实例化BeautifulReport模块
# run.report(filename='test',description='这个描述参数是必填的')


# 测试报告模板运行程序:unittestreport
# pip3 install unittestreport
import unittestreport
runner = unittestreport.TestRunner(suite, filename="report.html",
                 report_dir="./reports",
                 title='测试',
                 tester='张三',
                 desc="自测使用",
                 templates=4)
runner.run()

2.3.2 方法2

python 复制代码
# -*- coding: utf-8 -*-
"""
Author: zhangsan
date:   2024/12/18 14:36
Description:    

"""
import unittest
# 导入测试用例模块
from testcase.test_sum import TestSum

# 方法1:
# 第一步:创建TestSuite实例
# suite = unittest.TestSuite()

# 第二步:将测试用例添加至TestSuite
# 方式1,添加单条测试用例
# suite.addTest(TestSum('test_sum01'))  # addTest()里参数格式为:测试类('测试方法')
# suite.addTest(TestSum('test_sum02'))

# 方式2,添加多条测试用例
# suite.addTests([TestSum('test_sum01'), TestSum('test_sum02')])

# 方法2:
# 创建一个加载对象
# loader = unittest.TestLoader()
# suite.addTest(loader.loadTestsFromTestCase(TestSum))

# 方法3:不需要创建unittest.TestSuite()
test_dir = './testcase'
suite = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')

# 第三步:创建TextTestRunner实例
# 创建TextTestRunner实例
# runner = unittest.TextTestRunner()
# 使用run()方法运行测试套件(即运行测试套件中的所有用例)
# runner.run(suite)


# 生成测试报告:HTMLTestRunner无法安装,不能使用
# import HTMLTestRunner
# with open('./report/report.html', 'wb') as f:
#     runner = HTMLTestRunner.HTMLTestRunner(stream=f, title="测试报告", description="测试描述")
#     runner.run(suite)

#导入BeautifulReport模块,这个模块也是生成报告的模块,但是比HTMLTestRunner模板好看
# pip3 install BeautifulReport
from BeautifulReport import BeautifulReport as bf

run = bf(suite) #实例化BeautifulReport模块
run.report(filename='test',description='这个描述参数是必填的')


# 测试报告模板运行程序:unittestreport
# pip3 install unittestreport
# import unittestreport
# runner = unittestreport.TestRunner(suite, filename="report.html",
#                  report_dir="./reports",
#                  title='测试',
#                  tester='张三',
#                  desc="自测使用",
#                  templates=4)
# runner.run()
相关推荐
十年一梦实验室6 小时前
【C++】sophus : test_macros.hpp 用于单元测试的宏和辅助函数 (四)
开发语言·c++·单元测试
编码浪子12 小时前
Springboot3.x配置类(Configuration)和单元测试
单元测试
互联网杂货铺2 天前
单元测试总结
自动化测试·软件测试·python·测试工具·职场和发展·单元测试·测试用例
梧桐树04292 天前
python:单元测试
开发语言·python·单元测试
溟洵4 天前
【C++第三方库】快速上手---轻量级数据库SQLite和单元测试工具Gtest
数据库·c++·后端·单元测试·sqlite
测试老哥5 天前
如何写出优秀的单元测试?
自动化测试·软件测试·python·测试工具·职场和发展·单元测试·测试用例
栗子~~6 天前
单元测试-FATAL ERROR in native method: processing of -javaagent failed
单元测试
qq11561487077 天前
单元测试
单元测试
张一西7 天前
ARM学习(35)单元测试框架以及MinGW GCC覆盖率报告
单元测试·mingw·gcc·覆盖率·cppunit·gcov