语言互动网站建设,甘肃网站建设推广,网站建设黄页免费观看,虚拟云电脑目录#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结#xff08;尾部小惊喜#xff09; 前言
传统软件测试行业… 目录导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结尾部小惊喜 前言
传统软件测试行业是以手工测试为主也就是所谓的点点点加上国内软件公司不注重测试受制于大环境影响等也就给了大众一种测试人员虽然身处互联网行业却是毫无技术可言的工种。
话锋一转到了如今不得不说一声大人时代变了最直观的表现莫过于招聘要求的提高越来越要求测试人员拥有七十二变的能力。 而在这其中自动化测试能力是现在手工测试迈向更高技术岗位的必经之路。
搭建接口测试框架
构建接口测试思维 当前互联网产品最大的特点就是快上线周期通常是以天甚至是以小时为单位而传统软件产品的周期多以月甚至以年为单位。因此如何在保证产品质量下有效缩短测试回归时间成了重中之重。
两个突破口 引入测试的并发执行即从以往的串行执行测试用例采用分布式的方法并行执行。
从测试策略上找到突破口从传统软件产品的金字塔测试策略往菱形测试策略转变。以接口测试为主GUI测试为辅单元测试则根据公司实际情况进行。
四点建议 以中间层的API测试为重点做全面的测试 轻量级的GUI测试只覆盖最核心直接影响主营业务流程的E2E场景 最上层的GUI测试通常利用探索式测试思维以人工测试的方式发现尽可能多的潜在问题 单元测试只对那些相对稳定并且核心的服务和模块开展全面的单元测试而应用层或者上层业务只会做少量的
为何要搭建测试框架
开发自己的框架更能结合自身工作中的痛点难点来做一个针对性的解决使其扩展性更高后期也能接入CI/CD。
利用现有工具来进行接口测试随着项目的规模变大维护成本将会增大不利于管控。
工具本身具有一定的局限性如支持的协议比较单一。 不用纠结技术选型根据自身的技术实力和技术功底来选择而不要以开发工程师的技术栈来选择。
定义专属框架目录结构 test_case存放测试用例 test_data存放测试数据 report存放测试报告 common存放公共方法 lib存放第三方库 config存放环境配置信息 main框架主入口 fixture类似unittest中的setUp/tearDown的存在但功能远比他们强大
构建框架流程
在框架构建过程中由于篇符有限本文只涉及其中部分环节。
1、在common公共模块、封装定义框架专属的http请求能力
# !/usr/bin/python3
# -*- coding: utf-8 -*-
# Author: pan-li
import requestsclass HttpRequests(object):def __init__(self, url):self.url urlself.req requests.session()# 自定义请求头根据自身所在公司项目需求self.headers {Content-Type: application/json, User-Agent: Node midway-v2x Version/1.28.1}# 封装get请求def get(self, url, params, data, headersNone, cookiesNone):response self.req.get(urlurl, paramsparams, datadata, headersheaders, cookiescookies)return response# post请求def post(self, url, params, data, headersNone, cookiesNone):response self.req.post(urlurl, paramsparams, datadata, headersheaders, cookiescookies)return response# put请求def put(self, url, params, data, headersNone, cookiesNone):response self.req.put(urlurl, paramsparams, datadata, headersheaders, cookiescookies)return response# delete请求def delete(self, url, params, data, headersNone, cookiesNone):response self.req.delete(urlurl, paramsparams, datadata, headersheaders, cookiescookies)return response2、抽离URL生成url_conf.py在config文件中
import enumclass URLConf(enum.Enum):TEST_URL http://10.12.7.20:8443/v2x-omp/api/3、编写接口测试用例在test_case文件中第一版测试用例安装pytestpip install -U pytest
import os
import sys
import pytest
import json
from common.http_requests import *
from config.url_conf import URLConf
project_root os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(project_root)class TestV2x:classmethoddef setup_class(cls) - None:cls.url URLConf.TEST_URL.valuecls.http HttpRequests(cls.url)def setup(self) - None:self.headers {Content-Type: application/json, User-Agent: Node midway-v2x Version/1.28.1}self.http HttpRequests(self.url)def tearDown(self):passstaticmethoddef get_token():headers {Content-Type: application/json, User-Agent: Node midway-v2x Version/1.28.1}response TestV2x.http.post(urlURLConf.TEST_URL.value, data{cmd:signin,params:{userName:smarttest,password:72be4b7f62832c516b85fb26de59df53}}, headersheaders)token response.json()[detail][token]return tokendef test_001_queryArea(self):查询区域playload {cmd: queryArea, csrfToken: TestV2x.get_token(), params: {cityId: 320200}}response TestV2x.http.post(self.url, datajson.dumps(playload), headersself.headers)resultNote response.json().get(resultNote)assert resultNote, Successdef test_002_queryYearlyCheckCount(self):查询年检总数playload {cmd: queryYearlyCheckCount, Token: TestV2x.get_token(), params: {}}response TestV2x.http.post(self.url, datajson.dumps(playload), headersself.headers)resultNote response.json().get(resultNote)assert resultNote, SUCCESSdef test_003_queryTrafficEvent(self):查询交通事件playload {cmd: queryTrafficEvent, Token: TestV2x.get_token(), params: {}}response TestV2x.http.post(self.url, datajson.dumps(playload), headersself.headers)resultNote response.json().get(resultNote)assert resultNote, Successdef test_004_queryRsuCount(self):查询rsu总数playload {cmd: queryRsuCount, Token: TestV2x.get_token(), params: {}}response TestV2x.http.post(self.url, datajson.dumps(playload), headersself.headers)resultNote response.json().get(resultNote)assert resultNote, 查询路测设备数量成功def test_005_queryDeviceDetail(self):查询设备详情playload {cmd: queryDeviceDetail, params: {deviceId: 0086860703231572}, Token: TestV2x.get_token()}response TestV2x.http.post(self.url, datajson.dumps(playload), headersself.headers)resultNote response.json().get(resultNote)assert resultNote, 查询终端信息成功if __name__ __main__:pytest.main()4、显然前面的测试用例也是流水账似的还有很大的优化空间现在就来一步一步进行。
5、优化一利用feature特性优化前置和后置条件fixture目录下的v2x_fixture.py文件
import pytest
from common.http_requests import HttpRequests
from config.url_conf import URLConfpytest.fixture(scopefunction, autouseTrue)
def http():url URLConf.TEST_URL.valuehttp HttpRequests(url)return httppytest.fixture(scopefunction, autouseTrue)
def get_token(http):headers {Content-Type: application/json, User-Agent: Node midway-v2x Version/1.28.1}response http.post(urlURLConf.TEST_URL.value,data{cmd:signin,params:{userName:smarttest,password:72be4b7f62832c516b85fb26de59df53}},headersheaders)token response.json()[detail][token]return token上述在引入feature之后简化了http请求的调用重新定义http()来进行调用。之前每次接口的调用都要附带token参数现在把获取token的方法提取出来单独封装加上feature的装饰他会作用与每一个方法用起来更加方便。此处的token是依赖登陆接口之后返回的值可根据自身项目的需求封装。
6、优化二 为测试用例添加数据驱动模式
# 以第五个测试用例单独为例
pytest.mark.parametrize(deviceid, [0086860703231572, 0086337601270714, 0086822412608154])def test_005_queryDeviceDetail(self, http, get_token, deviceid):查询设备详情playload {cmd: queryDeviceDetail, params: {deviceId: deviceid}, Token: get_token}response http.post(urlURLConf.TEST_URL.value, datajson.dumps(playload), headersURLConf.HEADERS.value)resultNote response.json()assert resultNote.get(resultNote), 查询终端信息成功logger.info(查询终端信息成功)
直接利用pytest.mark.parametrize()装饰器第一个参数为参数名后边数组为测试数据用例当中同样添加形参deviceid在 pytest 中数据驱动是经由 pytest 自带的 pytest.mark.parametrize() 来实现的。 pytest.mark.parametrize 是 pytest 的内置装饰器它允许你在 function 或者 class 上定义多组参 数和 fixture 来实现数据驱动。
pytest.mark.parametrize() 装饰器接收两个参数
第一个参数以字符串的形式存在它代表能被被测试函数所能接受的参数如果被测试函数有多个参数 则以逗号分
第二个参数用于保存测试数据。如果只有一组数据以列表的形式存在如果有多组数据以列表嵌套元 组的形式存在
7、优化三 为测试用例添加标签此时用到pytest.ini配置文件放在项目任意位置都能生效有以下作用
为你的测试框架定制用例查找规则 为你的测试框架注册标签名称 指定查找用例起始目录
[pytest]
python_files test_* *_test test*
python_classes Test* test*
python_functions test_* test*markers smoke: marks tests as smoketest : marks tests as testlog : marks tests as log
# 使用时只需要在测试用例上使用pytest.mark.smoke即可
# 执行时pytest -m [标记名]8、优化四 配置pytest.ini文件集成日志收集和实时控制台打印功能
[pytest]
log_cli 1
log_cli_level DEBUG
log_cli_date_format %Y-%m-%d-%H-%M-%S
log_cli_format %(asctime)s - %(filename)s - %(name)s - %(module)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s
log_file ..\\report\\run.log
log_file_level DEBUG
log_file_date_format %Y-%m-%d-%H-%M-%S
log_file_format %(asctime)s - %(filename)s -%(name)s - %(module)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s关于字段的详解可以在终端输入pytest --help 查看
9、优化五 定制测试框架测试报告属于第三方应用放在lib目录中
这里我们使用目前市面上使用人数较多的一款开源测试报告框架Allure它支持绝大多数测试框架
安装方法
pip install -U allure-pytestgithub上下载最新版本放到lib目录并配置成系统环境变量 https://github.com/allure-framework/allure2/releases 使用方法
执行pytest命令并指定allure报告目录 pytest -v -s test_v2x_api_02.py --alluredir./allure_reports
在线生成allure报告allure serve allure_reports 生成本地allure报告allure generate allure_reports
当然这只是在控制台直接命令执行还不够方便如果我们想在其他环境运行就又得配置环境变量那么我们如何把它集成到我们的框架中呢
在共同方法中生成allure工具类以便分辨运行环境是windows还是mac
import os
import sys
import platformpath os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), lib)
allure_path os.path.join(path, allure, bin)
sys.path.append(allure_path)class Report():propertydef allure(self):if platform.system() Windows:cmd os.path.join(allure_path, allure.bat)else:cmd os.path.join(allure_path, allure)return cmd10、在main模块中添加执行调度策略
import os
import threading
import pytestfrom common.report import Reportproject_root os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
report_dir os.path.join(project_root, report)
result_dir os.path.join(report_dir, allure_result)
allure_report os.path.join(report_dir, allure_report)
report Report()def run_pytest():pytest.main([-v, -s, f--alluredir{result_dir}])def general_report():cmd {} generate {} -o {} --clean.format(report.allure, result_dir, allure_report)print(os.popen(cmd).read())if __name__ __main__:run threading.Thread(targetrun_pytest)gen threading.Thread(targetgeneral_report)run.start() # 多线程先执行pytest命令生成测试报告run.join()gen.start() # 报告生成后调用allure工具类生成本地报告11、最后一版测试用例整合前面的优化
import os
import sys
import json
from fixture.v2x_fixture import *
from config.url_conf import URLConf
project_root os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(project_root)class TestV2x:pytest.mark.smoke # 标签的使用def test_001_queryArea(self, http, get_token):查询区域playload {cmd: queryArea, csrfToken: get_token, params: {cityId: 320200}}response http.post(urlURLConf.TEST_URL.value, datajson.dumps(playload), headersURLConf.HEADERS.value)resultNote response.json()assert resultNote.get(resultNote), successlogger.info(查询区域成功)def test_002_queryYearlyCheckCount(self, http, get_token):查询年检总数playload {cmd: queryYearlyCheckCount, Token: get_token, params: {}}response http.post(urlURLConf.TEST_URL.value, datajson.dumps(playload), headersURLConf.HEADERS.value)resultNote response.json()assert resultNote.get(resultNote), SUCCESSlogger.info(查询年检成功)def test_003_queryTrafficEvent(self, http,get_token):查询交通事件playload {cmd: queryTrafficEvent, Token: get_token, params: {}}response http.post(urlURLConf.TEST_URL.value, datajson.dumps(playload), headersURLConf.HEADERS.value)resultNote response.json()assert resultNote.get(resultNote), Successlogger.info(查询交通事件成功)def test_004_queryRsuCount(self, http, get_token):查询rsu总数playload {cmd: queryRsuCount, Token: get_token, params: {}}response http.post(urlURLConf.TEST_URL.value, datajson.dumps(playload), headersURLConf.HEADERS.value)resultNote response.json()assert resultNote.get(resultNote), 查询路测设备数量成功# text response.text# print(text)logger.info(查询路侧设备成功)# 简单的数据驱动pytest.mark.parametrize(deviceid, [0086860703231572, 0086337601270714, 0086822412608154])def test_005_queryDeviceDetail(self, http, get_token, deviceid):查询设备详情playload {cmd: queryDeviceDetail, params: {deviceId: deviceid}, Token: get_token}response http.post(urlURLConf.TEST_URL.value, datajson.dumps(playload), headersURLConf.HEADERS.value)resultNote response.json()assert resultNote.get(resultNote), 查询终端信息成功logger.info(查询终端信息成功)if __name__ __main__:# 打印更详细的信息pytest.main([-s, -v, ])下面是我整理的2023年最全的软件测试工程师学习知识架构体系图
一、Python编程入门到精通 二、接口自动化项目实战 三、Web自动化项目实战 四、App自动化项目实战 五、一线大厂简历 六、测试开发DevOps体系 七、常用自动化测试工具 八、JMeter性能测试 九、总结尾部小惊喜
只要心中燃烧着不灭的激情勇敢面对困难与挑战坚持不懈地追求目标就能书写属于自己的辉煌篇章。相信自己的能力与潜力努力奋斗每一次努力都是一次进步每一次拼搏都是一次成长。奋斗不息成功必将绽放
不论前路多么曲折艰难只要心怀信念与勇气坚持不懈地奋斗才能创造属于自己的辉煌。相信自己的才华与潜力努力拼搏每一次奋斗都是一次进步每一次挑战都是一次成长。
勇往直前不畏艰难险阻只有坚持不懈的奋斗才能追逐梦想的光芒。相信自己的能力与潜力不断超越自我每一次努力都是一次成长每一次拼搏都是一次进步。