每一个TestCase(测试用例)都是一个代码文件, 在其中来书写真正的测试用例
代码必须按照标识符的规则来书写
导包
自定义测试类
在测试类中书写测试用例
执行用例
import unittest
class TestDemo(unittest.TestCase):
'自定义测试案例类,需要继承测试模块中中的TestCase类即可'
# 测试方法就是我们需要的用例代码
# 暂时我们用print代替
def test_method1(self):
print("测试方法一")
def test_method2(self):
print("测试方法二")
代码文件的名字以数字开头
代码文件名字中有空格
代码文件中有中文
其他特殊符号
(数字、字母、下滑线组成,不能以数字开头)
步骤:
导包
实例化套件对象(TestSuite)
使用套件对象添加用例方法
# 1. 导包
import unittest
from RayStuDayOne.testCxase import TestDemo
# 2. 实例化套件对象
suite = unittest.TestSuite()
# 3. 使用套件对象添加用例方法
suite.addTest(TestDemo('test_method1'))
suite.addTest(TestDemo('test_method2'))
# 这里也可以用下面的方法,只是idea没有提示
suite.addTest(unittest.makeSuite(类名))
注意 :
1. test方法必须以 test_ 开头,不然就不会生成测试方法,也就不会执行
2.
testSuite : 作用是打包管理测试用例(testCase)
TestRunner : 执行TestSuite(套件)
导包
实例化运行对象
使用运行对象去执行套件对象
# 1. 导包
import unittest
from RayStuDayOne.testCxase import TestDemo
# 2. 实例化套件对象
suite = unittest.TestSuite()
# 3. 使用套件对象添加用例方法
suite.addTest(TestDemo('test_method1'))
suite.addTest(TestDemo('test_method2'))
# 这里也可以用下面的方法,只是idea没有提示
suite.addTest(unittest.makeSuite(类名))
# 4. 实例化运行对象
runner = unittest.TextTestRunner()
# 5. 使用运行对象去执行套件对象 ,里面写套件对象
runner.run(suite)
需求 :
完成对add方法的测试
def add(a, b):
return a + b
步骤
导包
自定义测试类
在测试类中书写测试用例
import unittest
from Demo.tools import add
class testAdd(unittest.TestCase):
"""自定义测试类,实现测试方法的书写"""
def test_demo(self):
# 比较实际结果 和 预期结果是否相等
if add(1, 2) == 3:
print("测试通过!") # 现在暂时是用打印, 以后是直接靠断言
else:
print("测试不通过!")
def test_demo1(self):
# 比较实际结果 和 预期结果是否相等
if add(10, 11) == 22:
print("测试通过!")
else:
print("测试不通过!")
def test_demo2(self):
# 比较实际结果 和 预期结果是否相等
if add(11, 2) == 13:
print("测试通过!")
else:
print("测试不通过!")
步骤
导包
实例化套件对象(TestSuite)
使用套件对象添加用例方法
实例化运行对象
使用运行对象去执行套件对象
# 1. 导包
import unittest
from Demo.testDemo import testAdd
# 2. 使用Suite 和 Runner 管理testAdd(unittest.TestCase)文件
# 3. 实例化套件对象
suite = unittest.TestSuite()
# 4. 添加测试方法
suite.addTest(unittest.makeSuite(testAdd))
# 5. 实例化执行对象
runner = unittest.TextTestRunner()
# 6. 执行测试套件
runner.run(suite)
对TestSuite进行补充
管理多个TestCase
比如:
如果TestCase的代码文件有很多(10,20,30)
步骤:
1. 导包
2. 实例化测试加载对象 并添加测试用例 ---- 》 得到的是suite对象
3. 实例化运行对象
4. 运行对象执行套件对象
# 1. 导包
import unittest
import Case
# 2. 实例化加载对象 ,并添加用例
# discover 就是发现这个加载, 就可以将这个加载 作为suite对象来使用,同时 discover就可以按照通配符来进行匹配
# 比如我们这里匹配的就是Case目录下 的 以test开头的py文件
suite = unittest.TestLoader().discover('Case', 'test*.py')
# 3. 使用测试运行 来运行测试loader
runner = unittest.TextTestRunner()
runner.run(suite)
还可以简化
是一种 代码结构
在某种特定情况下, 会自动执行
需要就写 ,不需要就不用写
在每个测试方法(用例代码) 执行前后都会自动调用的结构
def setup(self):
# 在每个测试方法执行之前都会执行
pass
def teardown(self):
# 在每个测试方法执行之后都会执行
pass
在每个测试类中所有方法执行前后, 都会自动调用的结构(在整个类中, 执行之前执行之后各一次)
# 类级别的Fixture方法 , 是一个类方法
# 类中所有方法之前
@classmethod
def setupClass(cls):
pass
@classmethod
def tearDown(self):
pass
打开浏览器 ------------类级别
输入网址 ------------方法级别
输入用户名密码 验证吗点击登录 ---------测试方法
关闭当前页 ------------方法级别
关闭浏览器------------类级别
+++++++++++++++++++++++++++++++++++++
一值重复上述的结构
概念: 断言就是让程序代替人为判断测试程序执行结果是否符合预期结果的过程。
实现自动化测试
True:
用例通过
False:
用例未通过
序号 | 断言方法 | 断言描述 |
---|---|---|
1 | assertTure(expr,msg = None) | 验证expr是否为true,如果为false 。则fail |
2 | assertFalse(expr,msg = None) | 验证expr是否为false,如果为true 。则fail |
3 | assertEqual(expected,actual,msg = None) | 验证expected == actual, 不等则 fail |
4 | assertNotEqual(first,second) | 验证first != second ,相等为 fail |
。。。。有很多
self.aseertEqual(预期结果,实际结果)
相等 ,则预期通过。不相等则是不通过。
self.assertIn(预期结果,实际结果)
判读预期结果是否包含在实际结果中 实际>预期
包含则为true
def test_demo(self):
# 比较实际结果 和 预期结果是否相等
self.assertEqual(3, add(1, 2))
# 用上面的代替下面的
def test_demo1(self):
# 比较实际结果 和 预期结果是否相等
if add(10, 11) == 22:
print("测试通过!")
else:
print("测试不通过!")
他不会生成结果,如果测试失败他就不会通过,如果成功, 那么就会显示ok, 然后通过下面的步骤就可以导出测试报告。
参数化 在测试方法中, 通过使用 变量来代替具体的测试数据, 然后使用传参的方法将
数据传递给方法变量。
好处 : 相似的代码不需要重复读写
日常场景:
测试数据一般放在json数据中
使用读取json文件, 提取我们需要的数据
安装相关的插件 通过终端 : 输入
pip install parameterized
即可
步骤:
1. 导包
2. 定义测试类
3. 书写测试方法(用到的测试数据使用变量代替)
4. 组织测试数据并传参 (数据和顺序需要保证一致)
# 1. 导包
import unittest
from parameterized import parameterized
from Demo.tools import add
# 2. 定义测试类 ,书写测试方法 。(用到的测试数据使用变量代替)
class testAddOne(unittest.TestCase):
"""自定义测试类,实现测试方法的书写"""
@parameterized.expand(data) # 使用装饰器的方法传参
def test_demo(self, paramA, paramB, expect):
# 比较 预期结果 and 实际结果 是否相等
self.assertEqual(expect, add(paramA, paramB))
组织测试数据并传参
# 组织测试数据
组织数据的格式
# [(),(),()....] 或者 [[],[],[],[]....]
data = [
(1, 2, 3),
(11, 21, 32),
...
]
传参通过装饰器的方法(也就是Java中的注解形式)
@parameterized.expand(data) # 使用装饰器的方法传参
def test_demo(self, paramA, paramB, expect)
通过导入测试化数据的方式来完成测试
def build_Data():
data = [] # 用于接收数据
with open('H:\pythonStudy\Case\data.json', encoding='UTF-8') as f:
result = json.load(f) # f中是列表里面套元组的过程, 而我们需要的是列表里面套列表的形式
for i in result: # i 就是里面的每个数据 { XXX }
# 将数据存储到data中, 然后作为组织测试数据返回
data.append((i.get('param1'), i.get('param2'), i.get('param3')))
return data
class testAddOne(unittest.TestCase):
"""自定义测试类,实现测试方法的书写"""
@parameterized.expand(build_Data()) # 使用装饰器的方法传参
def test_demo(self, paramA, paramB, expect):
# 比较 预期结果 and 实际结果 是否相等
self.assertEqual(expect, add(paramA, paramB))
对一些未完成的 ,或者不满足测试条件的测试函数和测试类,可以跳过执行
直接将测试函数标记成为跳过
@unittest.skip('代码为完成')
# 根据条件判断测试函数是否跳过
@unittest.skipIf(condition,reason)
实现
class testAddOne(unittest.TestCase):
"""自定义测试类,实现测试方法的书写"""
version = 30
# @unittest.skipIf()
@parameterized.expand(build_Data()) # 使用装饰器的方法传参
def test_demo(self, paramA, paramB, expect):
# 比较 预期结果 and 实际结果 是否相等
self.assertEqual(expect, add(paramA, paramB))
@unittest.skipIf(version >= 30, '版本号大于等于30 ,不用测试')
def test_demo1(self):
# 比较实际结果 和 预期结果是否相等
if add(10, 11) == 22:
print("测试通过!")
else:
print("测试不通过!")
@unittest.skip("不想测试了")
def test_demo2(self):
# 比较实际结果 和 预期结果是否相等
if add(11, 2) == 13:
print("测试通过!")
else:
print("测试不通过!")
只有testCase的才能生成 ,使用testSuite 和 testRunner包装的套件对象无法生成
使用第三方的类库生成报告
将第三方的测试运行类模块放在当前代码的目录中
步骤 :
1. 导包unittest
2. 使用套件对象 ,加载对象, 去添加测试用例
3. 实例化第三方的运行对象, 并运行套件对象