自动化测试流程
需求分析。需求文档,接口文档。抓包接口
计划。进度?是否自动化?优先级?
测试用例(是从手工测试提取出来的)
评审
执行(写代码)
报告
1.需求分析
接到一个项目,在需求分析的阶段,我们需要熟悉的部分包含:
需求文档,功能展示以及交互
接口文档,后端数据是怎么传输
数据库账号,数据库地址,结构帮大家熟悉整个项目的轮廓,表字段
测试环境/环境怎么搭建
原型图
接口需求分析
接口文档形式:纸质文档(电子)open api(以前叫做swagger,在网站上进行访问)、什么都没有全凭一张嘴(自己抓包)
通过抓包,postman调试工具 ,我们知道了怎么设计用例,预期结果。
2.测试计划
测试计划一般由项目经理制定,主要是时间、技术、进度、优先级的管控,可以确认哪些功能需要引入自动化测试(自动化测试技术python/java)。
测试计划还会涉及到可行性分析,风险分析。
3.测试用例
测试用例的编写一般是在excel文档中实现的。
通常来说,任何的一个项目或者是新功能,会先进行手工测试,也是要进行全量的用例编写。
自动化测试主要应用场景:
冒烟测试:确认主流程是否能正常运行。
回归测试:验证问题并检查是否引起其他问题的测试
持续集成:一天可能要做好几次的测试,反复测试
excel编写,以前程贷注册接口为例。
注意:json数据一定要符合规范,不然转成字典会报错(引号必须是双引号)。预期结果根据postman运行后得出。
4.编写自动化测试用例函
如果领导给你一个自动化测试的计划,先不要着急做到十全十美,
第一步是验证你的自动化测试程序是否能正常运行,先把功能实现。
写一个单独的自动化测试用例函数。test_开头的测试用例函数,需要有请求发送,得到响应结果,断言。然后生成测试报告。
5、ddt
有了以上的基础后,我们可以引入ddt,优化下测试用例函数,降低代码重复率。
ddt适用的场景:不同的数据,测试步骤是一样的。
6、注册接口优化
- 测试报告展示不覆盖
- 注册的手机号码生成
- 全量断言和部分断言
6.1 测试报告展示不覆盖
现在测试报告每次都是生成report.html,每次生成都会覆盖。解决方式报告名称添加时间戳。
6.2 注册手机号生成
方案1:手工+1,号段运营商不支持,与别人的号码冲突;
方案2:数据库中原注册的手机号码清除(不一定有删除数据库的权限)
方案3:随机生成一个手机号random.randint
方案4:使用faker库伪造数据
common下新建helper.py文件:
from faker import Faker def generate_mobile(): faker = Faker(locale=['zh-cn']) # 生成手机号 return faker.phone_number()
test_register_ddt.py:
import unittest import requests from common.logger import my_log from common.excel import read_excel_dict from setting.config import case_file,host from ddt import ddt,data import json from common.helper import generate_mobile # 得到测试数据 cases = read_excel_dict(file=case_file,sheet_name='register') @ ddt class TestRegister(unittest.TestCase): @data(*cases) def test_register_01(self,info): my_log.info("测试用例正在执行") # 准备测试数据 # url = info['url'] # 域名和端口可以放在setting中,环境变化时方便修改 url = host + info['url'] method = info['method'] headers = json.loads(info['headers']) json_data = info['json'] # 检测如果json_data中存在某个标记,就说明需要自动生成一个手机号 if '#mobile_phone#' in json_data: mobile = generate_mobile() json_data = json_data.replace('#mobile_phone#',mobile) json_data = json.loads(json_data) expected = json.loads(info['expected']) # 发送接口请求,得到实际结果,headers、json传递的是字典,所以上面用json.loads将字符串装化成字典 resp = requests.request(url=url,method=method,headers=headers,json=json_data) actual = resp.json() # 预期结果和实际结果的断言 self.assertEqual(expected,actual)
运行结果:
从运行结果看,生成了随机的手机号,但用例失败,因为预期结果与实际结果不相符(id、mobile_phone),我们可以去掉一些无用的信息,比如:copyright
6.3 全量断言和部分断言
- 全量断言:预期结果与实际结果一个字不能差,麻烦
- 部分断言:提取有用的关键字进行断言。code、msg
修改用例中的expected,只保留code和msg
import unittest import requests from common.logger import my_log from common.excel import read_excel_dict from setting.config import case_file,host from ddt import ddt,data import json from common.helper import generate_mobile # 得到测试数据 cases = read_excel_dict(file=case_file,sheet_name='register') @ ddt class TestRegister(unittest.TestCase): @data(*cases) def test_register_01(self,info): my_log.info("测试用例正在执行") # 准备测试数据 # url = info['url'] # 域名和端口可以放在setting中,环境变化时方便修改 url = host + info['url'] method = info['method'] headers = json.loads(info['headers']) json_data = info['json'] # 检测如果json_data中存在某个标记,就说明需要自动生成一个手机号 if '#mobile_phone#' in json_data: mobile = generate_mobile() json_data = json_data.replace('#mobile_phone#',mobile) json_data = json.loads(json_data) expected = json.loads(info['expected']) # 发送接口请求,得到实际结果,headers、json传递的是字典,所以上面用json.loads将字符串装化成字典 resp = requests.request(url=url,method=method,headers=headers,json=json_data) actual = resp.json() # 预期结果和实际结果的断言 # 笨办法 多个字段分别断言 # self.assertEqual(expected['code'],actual['code']) # self.assertEqual(expected['msg'], actual['msg']) # 对expected进行for循环 for key, value in expected.items(): self.assertEqual(value, actual[key])
7、扩展
7.1 测试金字塔
从下往上:单元测试->服务(接口)测试->UI用户界面测试->系统测试(手工测试)
左侧代表:速度
右侧代表:成本
7.2 什么样的项目适合做自动化测试
需求稳定,不会频繁变更。(项目初期不太适合)
研发和测试周期长,需要频繁执行回归测试。
需要再多种平台上重复运行相同测试的场景。
某些测试项目通过手工测试无法实现,或者手工测试成本高。
被测软件的开发较为规范,能够保证系统的可测试性。
7.3 图片验证码
测试接口时,遇到图片验证码的问题,该怎么解决?
- 找开发直接关掉验证码的功能
- 找开发万能验证码
- 对接第三方平台(超级鹰)
- 代码的方式去实现验证码的操作对我们来说比较困难(OCR,图像识别,图像处理,机器学习(AI))
7.4 faker
7.5 代码调试
1、从报错信息中查看error message。
2、找到报错行,报错信息中哪个信息是自己写的,跳到行号。
3、如果有多个文件是自己编写的,行号都找出来。
4、哪一行报错,就在哪一行(或前一行)设置断点,通过debug调试。