软件测试-UnitTest
内容包括:UnitTest框架介绍、UnitTest组成、TestCase、TestSuite、TestRunner、TestLoader、Fixture、参数化、跳过等。
一、UnitTest框架介绍
虽然UnitTest常用于单元测试,但也是软测工程师必备的框架之一,因为它可以实现自动化脚本的功能,并能够运行多个测试用例。
二、UnitTest组件
2.1 TestCase
2.1.1 TestCase介绍
2.1.2 TestCase步骤
# 1、导包
import unittest
# 2、自定义测试类,需要继承unittest模板中的
class TestDemo1(unittest.TestCase):
# 3、书写测试方法,即用例代码。目前没有真正的用例代码,使用print代替。
# 书写要求,测试方法必须以test_开头(本质以test开头)
def test_method1(self):
print('测试方法1-1')
def test_method2(self):
print('测试方法1-2')
# 4、执行用例
# 4.1 将光标放在类的后面执行,会执行类中所有的测试方法
# 4.2 将光标放在方法名的后面执行,只执行当前的方法
2.1.3 TestCase常见问题
必须使用Python测试才行。
2.2 TestSuite&TestRunner
2.2.1 TestSuite&TestRunner介绍
2.2.2 TestSuite&TestRunner步骤
文件结构:
因为TestSuite是用来管理多个TestCase文件的,所以创建两个Case文件(test01、test02)和一个Suite文件(test03)。
test01.py:
# 1、导包
import unittest
# 2、自定义测试类,需要继承unittest模板中的
class TestDemo1(unittest.TestCase):
# 3、书写测试方法,即用例代码。目前没有真正的用例代码,使用print代替。
# 书写要求,测试方法必须以test_开头(本质以test开头)
def test_method1(self):
print('测试方法1-1')
def test_method2(self):
print('测试方法1-2')
# 4、执行用例
# 4.1 将光标放在类的后面执行,会执行类中所有的测试方法
# 4.2 将光标放在方法名的后面执行,只执行当前的方法
test02.py:
# 1、导包
import unittest
# 2、自定义测试类,需要继承unittest模板中的
class TestDemo2(unittest.TestCase):
# 3、书写测试方法,即用例代码。目前没有真正的用例代码,使用print代替。
# 书写要求,测试方法必须以test_开头(本质以test开头)
def test_method1(self):
print('测试方法2-1')
def test_method2(self):
print('测试方法2-2')
# 4、执行用例
# 4.1 将光标放在类的后面执行,会执行类中所有的测试方法
# 4.2 将光标放在方法名的后面执行,只执行当前的方法
test03.py:
# 学习 TestSuite 和 TestRunner 的使用
# 1、导包
import unittest
from test01 import TestDemo1
from test02 import TestDemo2
# 2、实例化(创建对象)套件对象
suite = unittest.TestSuite()
# 3、使用套件对象添加用例方法
# 方法一,套件对象.addTest(测试类名('方法名'))
suite.addTest(TestDemo1('test_method1'))
suite.addTest(TestDemo1('test_method2'))
suite.addTest(TestDemo2('test_method1'))
suite.addTest(TestDemo2('test_method1'))
# 4、实例化运行对象
runner = unittest.TextTestRunner()
# 5、使用运行对象去执行套件对象
# 运行对象.run(套件对象)
runner.run(suite)
test04.py(使用另一种方法添加):
# 学习 TestSuite 和 TestRunner 的使用
# 1、导包
import unittest
from test01 import TestDemo1
from test02 import TestDemo2
# 2、实例化(创建对象)套件对象
suite = unittest.TestSuite()
# 3、使用套件对象添加用例方法
# 方法二,将一个测试类中的所有方法进行添加
# 套件对象.addTest(unittest.makeSuite(测试类名))
suite.addTest(unittest.makeSuite(TestDemo1))
suite.addTest(unittest.makeSuite(TestDemo2))
# 4、实例化运行对象
runner = unittest.TextTestRunner()
# 5、使用运行对象去执行套件对象
# 运行对象.run(套件对象)
runner.run(suite)
运行结果:
2.2.3 案例
问题描述:测试tools模块中的add()函数是否正常。
tools.py:
def add(a, b):
return a + b
代码:
TestCase:
import unittest
from tools import add
class TestAdd(unittest.TestCase):
def test_method1(self):
if add(1, 2) == 3:
print('测试通过')
else:
print('测试不通过')
def test_method2(self):
if add(10, 20) == 30:
print('测试通过')
else:
print('测试不通过')
def test_method3(self):
if add(15, 25) == 40:
print('测试通过')
else:
print('测试不通过')
运行结果:
TestSuite&TestRunner:
代码:
import unittest
from test11 import TestAdd
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAdd))
runner = unittest.TextTestRunner()
runner.run(suite)
运行结果:
2.3 TestLoader
2.3.1 TestLoader介绍
2.3.2 TestLoader步骤
创建三个TestCase文件
Case代码和上述的代码类似
test01.py:
# 1、导包
import unittest
# 2、自定义测试类,需要继承unittest模板中的
class TestDemo1(unittest.TestCase):
# 3、书写测试方法,即用例代码。目前没有真正的用例代码,使用print代替。
# 书写要求,测试方法必须以test_开头(本质以test开头)
def test_method1(self):
print('测试方法1-1')
def test_method2(self):
print('测试方法1-2')
# 4、执行用例
# 4.1 将光标放在类的后面执行,会执行类中所有的测试方法
# 4.2 将光标放在方法名的后面执行,只执行当前的方法
testLoader.py:
# 1、导包
import unittest
# 2、实例化对象并添加用例
# unittest.TestLoader().discover('例所在的路径','用例的代码文件名')
# 用例所在的路径,建议使用相对路径,用力的代码文件名可以使用*(任意多个任意字符)通配符
suite = unittest.TestLoader().discover('./case', '*')
# # 3、实例化运行对象
# runner = unittest.TextTestRunner()
# # 4、执行
# runner.run(suite)
# 可以将3 4步变为一步
unittest.TextTestRunner().run(suite)
运行结果:
使用相对路径把case文件中的三个TestCase文件全部导入,一步测试了。
2.4 Fixture
2.4.1 Fixture介绍
2.4.2 Fixture级别
1、方法级别
2、类级别
3、模块级别
2.4.3 Fixture案例
实现如下功能:
问题分析:
打开浏览器和关闭浏览器分别在开始和末尾,且整个过程只出现一次,所以是类级别。
输入网址在每次测试时都会用到,所以是方法级别。
输入用户名和密码属于测试方法。
代码:
import unittest
class TestLogin(unittest.TestCase):
# 每个测试方法执行之前都会先调用的方法
def setUp(self):
print("输入网址")
# 每个测试方法执行之后都会先调用的方法
def tearDown(self) -> None:
print('关闭当前页面')
@classmethod
def setUpClass(cls) -> None:
print('1.打开浏览器')
@classmethod
def tearDownClass(cls) -> None:
print('5.关闭浏览器')
def test_1(self):
print('输入正确用户名密码验证码,点击登录1')
def test_2(self):
print('输入错误用户名密码验证码,点击登录2')
运行结果:
导出测试报告:
三、参数化
3.1 参数化介绍
3.1.1 参数化定义
3.1.2 插件安装
可以使用 pip install parameterized 安装参数化插件。
3.2 参数化步骤
3.2.1 代码
四、跳过
4.1 跳过介绍
4.2 使用步骤及代码
4.2.1 代码
import unittest
version = 30
class TestDemo(unittest.TestCase):
# 使用skip装饰器表示跳过
@unittest.skip('没什么原因')
def test_1(self):
print('测试方法1')
@unittest.skipIf(version >= 30, '版本大于等于30,不用测试')
def test_2(self):
print('测试方法2')
def test_3(self):
print('测试方法3')
4.2.1 运行结果
可以发现,跳过了测试方法1,并根据判断跳过了不满足条件的测试方法2.