网站建设视频教程集,微信代码小程序,广州制作网站哪家专业,自助建站系统 破解前言
在Python的测试框架中#xff0c;我们通常会针对某个系统进行测试用例的维护#xff0c;在对庞大系统进行用例维护时#xff0c;往往会发现很多测试用例是差不多的#xff0c;甚至大多数代码是一样的。
故为了提高我们测试用例维护的效率#xff0c;在本文中#…
前言
在Python的测试框架中我们通常会针对某个系统进行测试用例的维护在对庞大系统进行用例维护时往往会发现很多测试用例是差不多的甚至大多数代码是一样的。
故为了提高我们测试用例维护的效率在本文中我们将探讨如何自己设计脚本自动生成测试用例脚本。
自动发现测试原理
pytest的一个重要特性就是它可以自动发现并运行测试。所以我们只需要按照一定的命名规则来命名测试文件和测试函数然后pytest就可以自动找到并运行这些测试。
默认情况下pytest会运行所有名称以test_开头或者以_test结尾的.py文件中的测试。在这些文件中pytest会运行所有名称以test_开头的函数或者方法。 例如以下代码定义了一个测试函数
def test_addition():assert 1 1 2
你可以把这个函数保存在一个名为test_example.py的文件中然后在命令行中运行pytest命令pytest就会自动找到并运行这个测试。
接口测试数据维护
为了达到目的所以我们约定以特定规则进行接口测试数据的维护我们选择json类型文件进行维护文件目录结构如下
需要注意的是考虑到维护的便利性我们推荐根据模块进行分层管理接口数据文件。 读取接口测试文件信息方法
有了接口数据文件那么我们就可以设计一个方法根据传入的接口模块、接口名称进行相应的接口文件地址拼接从而去读取json文件内容代码如下
class GetTestData:获取测试数据封装模块def __init__(self, logger):self.test_data_path FilePathSetting.test_data_path # 获取测试数据配置路径self.logger loggerdef get_api_data(self, api_module, api_name):根据接口模块和接口名称 获取接口配置信息:param api_module:接口模块:param api_name:接口名称:return:# 拼接需要读取接口模板信息的*.json文件路径地址api_data_path os.path.join(os.path.join(self.test_data_path, api_module), api_name)self.logger.info({init_api_data} 接口模板文件地址%s % api_data_path)# 读取接口模板路径下的*.json信息with open(fileapi_data_path, moder, encodingutf-8) as f:api_data json.load(f)self.logger.info({init_api_data} 接口模板信息%s % json.dumps(api_data, ensure_asciiFalse))return api_datadef get_case_data(self, pytest_current_test):根据传入的test_*.py路径 获取case配置信息:param pytest_current_test::return:# self.logger.info(~~~~~~~~~~~~ {init_api_data} 初始化当前接口请求模板数据 ~~~~~~~~~~~~)self.logger.info({init_api_data} 当前test_case位置信息:%s % pytest_current_test)# 根据传入的test_*.py路径 获取接口所属模块文件名称file_path pytest_current_test.split(::Test)[0]self.logger.info({init_api_data} 当前接口test_case文件地址:%s % file_path)# 根据传入的test_*.py路径 获取接口所属模块文件名称api_module os.path.split(os.path.split(file_path)[0])[1]self.logger.info({init_api_data} 接口所属模块%s % api_module)# 根据传入的test_*.py路径 获取接口模板*.json名称# # api_name os.path.split(file_path)[1].replace(.py, .json).replace(test_, )api_name os.path.split(file_path)[1][5:].replace(.py, .json) # 1、截取第6个字符到结尾2、将.py后缀替换为.jsonself.logger.info({init_api_data} 接口模板文件名称%s % api_name)return self.get_api_data(api_module, api_name)
现在我也找了很多测试的朋友做了一个分享技术的交流群共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源没人解答问题坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化性能安全测试开发等等方面有一定建树的技术大牛
分享他们的经验还会分享很多直播讲座和技术沙龙
可以免费学习划重点开源的
qq群号691998057【暗号csdn999】 基础的测试用例模板
因为我们基础的测试用例是通用的如以下代码实例
import allure
import pytestfrom utils.assertion.assert_controller import AssertController
from utils.requests_tools.requests_client import RequestClientapi_module 接口模块***
api_name 接口名称***allure.epic(api_module)
allure.feature(api_module api_name)
class TestCaseGroup:allure.title(接口健康检查)allure.description(接口返回信息基础验证)pytest.mark.smokedef test_smoke(self, init_api_data):# 获取环境配置信息接口测试数据env_data, case_data init_api_data# 获取接口返回信息res RequestClient(case_data).get_api_response()# 进行断言验证AssertController(case_data.assert_data).assert_equality(res.response_data)
故我们就可以设计一个用例模板的生成器
import datetime
from typing import Textdef write_case(file_path: Text, page: Text) - None: 写入用例数据 with open(file_path, w, encodingutf-8) as file:file.write(page)def write_init_file(*, file_path: Text) - None:初始化文件写入:param file_path: __init__文件地址:return:now datetime.datetime.now().strftime(%Y/%m/%d %H:%M)page f#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author : gmluo1988
# Software : PyCharm
# File : __init__.py.py
# Time : {now}
write_case(file_pathfile_path, pagepage)def write_test_case_file(*,api_module: Text,api_name: Text,filename: Text,case_path: Text) - None:标准测试用例文件写入:param api_module: 接口所属模块:param api_name: 接口名称名称:param filename: 用例文件名称:param case_path: 用例文件地址now datetime.datetime.now().strftime(%Y/%m/%d %H:%M)page f#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author : gmluo1988
# Software : PyCharm
# File : {filename}
# Time : {now}import allure
import pytestfrom utils.assertion.assert_controller import AssertController
from utils.requests_tools.requests_client import RequestClientallure.epic({api_module})
allure.feature({api_module} {api_name})
class TestCaseGroup:allure.title(接口健康检查)allure.description(接口返回信息基础验证)pytest.mark.smokedef test_smoke(self, init_api_data):# 获取环境配置信息接口测试数据env_data, case_data init_api_data# 获取接口返回信息res RequestClient(case_data).get_api_response()# 进行断言验证AssertController(case_data.assert_data).assert_equality(res.response_data)
write_case(file_pathcase_path, pagepage)有了测试用例生成器那么我们就可以根据接口模块接口名称以及接口相关信息生成通用的接口用例文件了。
自动生成测试用例
接下来要做事情就是读取test_data目录下所有模块下的接口文件遍历文件列表进行测试用例的字段生成。
要注意的是
1、该封装方法可以根据需求设置需要排除的文件列表
2、test_case目录下已经存在的用例会跳过生成
3、该封装方法生成的是一个基本通用的用例可在生成的用例基础上进行改造 import osfrom common.file_path_setting import FilePathSetting
from utils.case_automatic.test_case_template import write_test_case_file, write_init_file
from utils.get_test_data_tools.get_case_data import GetCaseDataclass CaseAutoGenerate:测试用例自动生成工具def __init__(self):设置需要排除的文件列表一般是Cloud登录以及子系统跳转登录等前置条件接口文档self.excluded_file_list [(users, login.json),(users, change_password.json)]def get_test_data_files(self) - list:获取所有测试数据文件路径信息列表每条测试数据由一个tuple组成包含3个值filename文件名parent_dir父级目录名称file_path文件地址需要排除不需要自动生成测试用例的文件:return:测试数据文件路径信息列表file_info_list [] # 所有测试数据文件路径信息列表# 获取测试数据目录所有文件下的子文件名称for root, dirs, filenames in os.walk(FilePathSetting.test_data_path):for filename in filenames:parent_dir os.path.basename(root) # 测试数据文件父级目录名称file_path os.path.join(root, filename) # 测试数据文件地址# 需要排除不需要自动生成测试用例的文件if (parent_dir, filename) not in self.excluded_file_list:# 每条测试数据由一个tuple组成包含3个值filename文件名parent_dir父级目录名称file_path文件地址file_info_list.append((filename, parent_dir, file_path))# 返回所有测试数据文件路径信息列表return file_info_liststaticmethoddef get_test_case_files() - tuple:获取所有测试用例父级目录列表测试用例文件地址列表需要将__init__.py, conftest.py文件进行过滤:return:case_dir_list [] # 用例父级目录列表case_path_list [] # 测试用例文件地址列表# 获取测试用例目录下所有文件下的子文件名称for root, dirs, filenames in os.walk(FilePathSetting.test_case_path):for filename in filenames:parent_dir os.path.basename(root)file_path os.path.join(root, filename)# 需要将__init__.py, conftest.py文件进行过滤if filename not in [__init__.py, conftest.py]:case_path_list.append(file_path)# 如果父级目录还未收录则进行父级目录列表更新并将__pycache__排除if parent_dir not in case_dir_list and parent_dir not in [__pycache__]:case_dir_list.append(parent_dir)# 分别返回测试用例父级目录列表测试用例文件地址列表return case_dir_list, case_path_liststaticmethoddef mk_dir(test_data_file_info: tuple, existing_case_dir_list: list) - None:创建测试用例父级目录如果测试数据文件的父级目录在测试用例目录中是不存在则在test_case目录下创建相同名称的package文件以及__init__.py文件:param test_data_file_info: 测试数据文件信息包含3个值filename文件名parent_dir父级目录名称file_path文件地址:param existing_case_dir_list: 已有的所有测试用例父级目录列表:return:test_data_dir test_data_file_info[1] # 测试数据文件父级目录名称# 如果测试数据文件的父级目录在测试用例目录中是不存在则在test_case目录下创建相同名称的package文件以及__init__.py文件if test_data_dir not in existing_case_dir_list:print(test_case下缺少:{} 文件目录,进行文件新增操作....format(test_data_dir))创建相同名称的package文件dir_path os.path.join(FilePathSetting.test_case_path, test_data_dir)os.makedirs(dir_path, exist_okTrue)新增__init__.py文件init_file_path os.path.join(dir_path, __init__.py)# open(init_file_path, w).close()write_init_file(file_pathinit_file_path)staticmethoddef is_case_exist(test_data_file_info: tuple, existing_case_path_list: list) - tuple:判断测试用例是否存在如果不存在则返回需要生成测试用例的文件名和文件地址信息如果已经存在对应的测试用例则返回None:param test_data_file_info::param existing_case_path_list::return:target_case_filename, target_case_file_pathtest_data_filename test_data_file_info[0] # 测试数据文件名称test_data_dir_name test_data_file_info[1] # 测试数据文件所属父级目录名称# 拼接目标测试用例所属父级目录地址target_case_dir_path os.path.join(FilePathSetting.test_case_path, test_data_dir_name)# 组装目标测试用例文件名称测试用例以“test_”开头将文件格式“.json”替换成“.py”target_case_filename test_ test_data_filename.replace(.json, .py)# 拼接目标测试用例文件地址target_case_file_path os.path.join(target_case_dir_path, target_case_filename)# if target_case_file_path in existing_case_path_list:# print(target_case_file_path)if target_case_file_path not in existing_case_path_list:# 返回需要生成测试用例的文件名和文件地址信息return target_case_filename, target_case_file_pathelse:return None, Nonedef case_automatic(self) - None:测试用例自动生成入口:return:获取所有测试数据文件路径信息列表test_data_file_info_list self.get_test_data_files()获取所有测试用例父级目录列表测试用例文件地址列表existing_case_dir_list, existing_case_path_list self.get_test_case_files()遍历每个测试数据文件,如果对应的测试用例不存在则进行测试用例自动生成操作for test_data_file_info in test_data_file_info_list:创建测试用例父级目录self.mk_dir(test_data_file_info, existing_case_dir_list)返回需要生成测试用例的文件名和文件地址信息target_case_filename, target_case_file_path self.is_case_exist(test_data_file_info,existing_case_path_list)创建对应的测试用例文件if target_case_filename and target_case_file_path:print(测试用例文件{} 不存在,进行测试文件新增....format(target_case_file_path))test_data_file_path test_data_file_info[2]case_data GetCaseData().get_api_data_by_path(test_data_file_path)api_module case_data.api_moduleapi_name case_data.api_namewrite_test_case_file(api_moduleapi_module,api_nameapi_name,filenametarget_case_filename,case_pathtarget_case_file_path)if __name__ __main__:print(Generating test case...)case_auto_generate CaseAutoGenerate()case_auto_generate.case_automatic()
总结
Python中通过自己设计脚本从而能够自动生成测试用例脚本提高我们测试用例维护的效率当然不同的系统可能有自己特别的方式在此是为大家作个参考。
下面是配套资料对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴我走过了最艰难的路程希望也能帮助到你 最后 可以在公众号自动化测试老司机 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。
如果我的博客对你有帮助、如果你喜欢我的博客内容请 “点赞” “评论” “收藏” 一键三连哦