小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
前言
软件开发流程中,我们都听说过瀑布开发流程,哪一定对开发各个环节有一定的了解吧。
在瀑布开发流程主要分为三大部分
- 前期需求设计阶段
- 编码实现阶段
- 测试验证阶段
作为测试来说,我们主要是参与第3部分测试环节的验证。根据介入时间早晚一次有单元测试、集成测试等
单元测试,与RD编码阶段是紧密连接的,如何在前期编码时就把绝大多数的BUG扼杀在摇篮里。其对于产品而言是无法省略的。
对于,python来说内置库也提供我们单元测试模块-unittest,本期我们将对unittest相关的方法进行学习,Let's go~
1. unittest 模块概述
unittest 是Python内置库提供用于进行单元测试的模块,其结构与JUnitd等主流单元测试框架类似。
Unittest支持的功能
- 支持测试自动化
- 配置共享
- 支持测试用例聚合到测试集中
- 测试与报告框架独立
Unittest使用方法
- 导入unittest模块:import unittest
- 测试类需要继承unitest.TestCase
- 测试用例必须以test开头
- assert断言来判断测试结果
- 使用HTMLTestRunner生产测试报告
2. unittest 结构组成
unitest 模块由五部分构成
-
Testcase 测试用例
- Testcase 对应我们平时就是一条完整的测试项。
- 测试项包含前置条件、步骤以及预期结果。
- 一个Testcase等价于一个测试单元
-
Testsuit 测试套件
- Testsuit由多个测试单元Testcase组成,可对一个功能进行完整验证
- 可以通过addTest来将Testcase加入到Testsuit中
- Testsuit也可以嵌套其他的Testsuit
-
TestRunner 测试执行
- 对测试套件提供执行策略和执行结果
- 通过TextTextRunner().run()来执行Testsuit或者Testcase
- TestRunner 支持使用图形界面、文本界面等表示测试执行结果
-
TestFixture 测试前后置
- 对于测试执行前,进行环境搭建和销毁
- 通过Testcase的setUP()和tearDown()方法来实现
3. unittest 工作原理
通过unittest五大部分了解后,它们执行过程图所示:
- 创建的testcase需要继承unittest.TestCase
- testcase里面包含许多方法,则方法需要以test开头
- 使用TestLoader对Testcase加载到Testsuite
- TextTestRunner对Testsuit进行执行,并将够保存在TextTestResult
- 默认情况下,TextTestResult执行结果会输出到控制台上
4. unittest 相关方法
unittest 库常用的属性和方法:
- 新键的测试用例都需要继承unittest.TestCase类 unittest.Testcase 提供对测试环境搭建和销毁的方法
| 方法 | 作用 |
|---|---|
| setUp() | 对测试环境进行前置操作 |
| tearDown() | 对测试环境进行后置操作 |
| setUpClass() | Testcase中test方法执行前置操作 |
| tearDownClass() | Tescase中test方法执行后置操作 |
📢setUpClass()、tearDownClass()
- 必须使用@classmethod装饰器
- 所有case运行完后只运行一次
- TestCase中还提供对方法进行控制的装饰器
| 装饰器 | 作用 |
|---|---|
| @unittest.skip(reason) | 跳过此步骤 |
| @unittest.skipIf(condition,reason) | 当condition为真,跳过此步骤 |
| @unittest.skipUnless(condition,reason) | 除非condition为真,否则跳过此步骤 |
| @unittest.expectedFailure | 标记此步骤异常 |
5. 小试牛刀
我们根据前对unittest的相关方法的学习,哪我们来使用unittest对方法进行测试吧
- mathfunc.py
def add(a, b):
return a+b
def minus(a, b):
return a-b
def multi(a, b):
return a*b
def divide(a, b):
return a/b
- unittest单元测试脚本
import unittest
from test import mathfunc
class TestMathFunc(unittest.TestCase):
"""Test mathfuc.py"""
def setUp(self) -> None:
print ("-----setup")
def tearDown(self) -> None:
print ("----teardown")
#setUpClass():必须使用@classmethod 装饰器,所有case运行前只运行一次
@classmethod
def setUpClass(cls) -> None:
print("This Setupclass() method only called once")
#tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次
@classmethod
def tearDownClass(cls) -> None:
print("this teardownclass() method only called once")
@unittest.skipUnless(3>2,"不执行")
def test_add(self):
"""Test method add(a, b)"""
print ("---add")
self.assertEqual(3, mathfunc.add(1, 2))
self.assertNotEqual(3, mathfunc.add(2, 2))
@unittest.skip("不执行此用例")
def test_minus(self):
"""Test method minus(a, b)"""
print ("---minus")
self.assertEqual(1, mathfunc.minus(3, 2))
@unittest.skipIf(3<2,"执行此用例")
def test_multi(self):
"""Test method multi(a, b)"""
print ("---multi")
self.assertEqual(6, mathfunc.multi(2, 3))
@unittest.expectedFailure
def test_divide(self):
"""Test method divide(a, b)"""
#self.skipTest("不执行")
print ("---divide")
self.assertEqual(2, mathfunc.divide(6, 3))
self.assertEqual(2.5, mathfunc.divide(5, 0))
if __name__ == '__main__':
#所有用例都执行一遍
# unittest.main()
- 选择执行 test_add、test_minus两个方法
if __name__ == '__main__':
#单独运行目标关键字更新
suite = unittest.TestSuite()
tests = [TestMathFunc("test_add"),TestMathFunc("test_minus")]
suite.addTests(tests)
unittest.TextTestRunner().run(suite)
总结
本期,我们对Python提供的unittest单元测试模块,对其工作原理以及unittest执行步骤进行了解和学习。
我们在写自动化用例后,可以使用unittest测试验证我们用例正确和稳定性。
以上是本期内容,欢迎大佬们点赞评论,下期见~