目录
前言
搭建过程:
一阶段,
二阶段,
三阶段,
四阶段
下面具体的说一下搭建过程
一阶段:
二阶段:
三阶段:
四阶段
前言
背景:公司需要每一个项目组都搭建自己的一套自动化测试框架,编写测试用例,用于完善公司的测试流程,不限制形式。
核心技术栈:testng+jenkins+maven+dubbo
开发人力:1(80%)
测试人力:1(30%)
耗时:4个月左右
Python自动化测试:2023最新合集Python自动化测试开发框架【全栈/实战/教程】合集精华,学完年薪40W+_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1AF411T7qJ/?spm_id_from=333.999.0.0
搭建过程:
搭建过程大致分为4个阶段:
一阶段,
原始需求:由工程效能组的同事提供一个封装了testng的j框架,给每一个项目组用于编写自动化测试用例,原本的意图是由开发配合测试同学编写代码,用于完成自动化测试用例。于是,按照这一需求,本人开始编写代码,完成测试用例。由于需求简单,所以只编写简单的框架,方便测试同学拷贝,黏贴。起初由本人编写一些复杂的用例,后续其他的用例,由测试同学仿照我的用例进行编码,完成剩余的测试用例。
结果表现
1,,在实施的过程中,发现重复逻辑过多
2,工程效能组提供的框架太简陋
3,最重要的问题,可以说绝大多数的测试同学看不懂代码,更不要说编码能力如何,这几乎为零,导致测试用例无法编写,压力全部由开发承担,且不易于维护。
二阶段,
更改需求:由本项目组架构师提出我们内部自行更改需求,具体表现为,让测试同学不再编写代码,通过配置驱动,完成测试用例。此时由于未曾有过这方面的经验,虽然完成功能,但是效果并不理想
结果表现
1,测试同学能够开始编写测试用例
2,配置凌乱且过多
三阶段,
优化二阶段的成果:具体如下
1,全面优化二阶段配置,减少配置文件,减少不必要的配置项
2,完善框架功能,修复bug
3,优化代码
结果表现
1,用例配置文件减少,配置项减少,测试同学编写用例速度大幅提升
2,根据测试同学提供的反馈信息,进一步完善功能
3,不断优化代码,便于维护
四阶段
进一步需求:由于测试用例以配置驱动,但jenkins服务器无法直接上传配置文件,所以提供web项目辅助测试同学
结果表现:
1,测试同学可自行编写测试用例,上传到jenkins服务器
2,测试同学可通过web项目,自行校验测试用例是否编写正确,便于修改
下面具体的说一下搭建过程
接口类:
1,调用接口前,需要做数据的植入
2,调用接口前,需要做配置的变更
3,调用接口
4,恢复配置
5,删除植入的数据
一阶段:
第一个阶段其实做的事情比较简单,主要分为2个,第一个是需求分析,第二个是硬编码
1,需求分析
根据需求,先分析项目组多个系统,发现基本归于2类,一类是接口,一类是定时任务。接口和定时任务分为多种,需要分类,
接口的校验分2种,一种是校验返回结果的,一种是校验落库数据的。这个又可以细分,比如一个接口,入参不同,返回结果不同,此为一个接口多个场景等。
定时任务的校验分2种,一种是校验落库数据的,一种是校验生成文件的。
2,硬编码
根据需求分析,先编写接口类测试用例,其中就是硬编码。
分析:在这个阶段,主要是基于testng进行编写测试用例,基本是硬编码,由jenkins执行,生成报告。
1,工程效能组同事提供的框架,只支持csv格式的入参和硬编码入参,非常不好用。
2,连接数据库使用jdbc,需要自己二次封装。
3,框架中无常用开发框架如spring,mybatis等
4,由于公司有防火墙及各种客观硬件原因,导致如果框架中引入spring,会导致jenkins在运行过程中耗时极其严重,不得不放弃使用spring等框架
5,由硬编码写出大概10个接口的部分场景,积累了经验
主要问题与难点:
1,框架提供的接口入参不好用
2,编写代码过多,不易于维护
解决方案:
1,自行开发json文件入参,xml文件入参等功能
二阶段:
根据新的需求,使用配置驱动,后参考的模型为tomcat。
简单分析一下:
tomcat是我们比较常用的一个web服务器,它是以修改配置文件来完成我们所需要的功能的,但是我们一般简单使用的话,就是修改一下端口,不过tomcat仍提供大量配置供我们修改用于完成我们的需求,基于这一特性,我们需要制定一套规则
1,配置驱动
2,提供可选配置,如果用户不配置,那么以默认的配置为主,如果用户配置,以用户的配置为主
3,自定义一套规则,以properties文件的形式来驱动
分析:
1,properties文件只能配置简单的key-value,如果完成复杂的配置,则无能为力
2,规则太繁琐
主要问题与难点:
1,以配置驱动,一个用例中含有多个接口,多个接口间有参数依赖关系,比如一个CASE含有N个接口,A接口的入参有一个属性是C接口的入参,B接口的出参有一个属性是C接口的入参,ABC有顺序执行关系,在配置中如何体现
2,如何以配置驱动,完成校验规则
解决方案:(由于已废弃,后面详述)
1,自定义传参的规则
2,自定义校验规则
Python自动化测试视频教程:2023最新合集Python自动化测试开发框架【全栈/实战/教程】合集精华,学完年薪40W+_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1AF411T7qJ/?spm_id_from=333.999.0.0
三阶段:
此时在二的成果上,进行优化,全面修改规则,目标
1,配置少而精
分析:
1,由于properties文件无法编写复杂规则,放弃properties文件,
2,二阶段的问题,一个CASE中N个接口相互依赖或独立,如何在配置中体现
3,校验规则策略问题
解决方案:
1,使用xml文件代替
具体实现
1,自定义xml文件,以CASE的名字命名(可自定义)
2,xml文件格式大致如下,很多配置记不清楚了,基本的如此
<?xml version="1.0" encoding="ISO-8859-1"?>
<testcase id="0" name="xxx">
<!--第一组接口-->
<group id="0" name="xxx-1">
<!--DUBBO接口全路径,必须配置-->
<service>com.xxx.service</service>
<!--DUBBO接口入参全路径,可不配置,可通过反射获取,基于一个服务一个方法,一个入参,一个出参,若配置了,以配置的为主-->
<request>com.xxx.request</request>
<!--DUBBO接口出餐全路径,可不配置,可通过反射获取,基于一个服务一个方法,一个入参,一个出参,若配置了,以配置的为主-->
<response>com.xxx.response</response>
<!--DUBBO接口方法,可不配置,可通过反射获取,基于一个服务一个方法,一个入参,一个出参,若配置了,以配置的为主-->
<method>method</method>
<!--DUBBO接口入参json串,必须配置-->
<data>
{
"key":"value",
“key1”:"value",
}
</data>
<!--DUBBO接口预计出参,可不配置,可默认就是此配置,此处仅校验返回码和message,若配置了,以配置的为主-->
<returnDate>
{
"code":"00",
"message":"成功"
}
</returnDate>
<!--DUBBO接口校验策略,可不配置,默认为此类型校验策略,若配置了,以配置的为主-->
<strategy>default</strategy>
</group>
<!--第二组接口,以下为最简配置-->
<group id="1" name="xxx-2">
<!--DUBBO接口全路径,必须配置-->
<service>com.xxx.service</service>
<!--DUBBO接口入参json串-->
<data>
{
"key":"value"
}
</data>
</group>
<!--第三组接口-->
<group id="2" name="xxx-3">
<!--DUBBO接口全路径,必须配置-->
<service>com.xxx.service</service>
<!--DUBBO接口入参json串,此处自定义规则传递参数,group.0代表id=0的group,request代表入参,key代表入参中的属性名-->
<data>
{
"key":"#{group.0.request.key}",
"key1":"#{group.1.response.key}",
}
</data>
</group>
</testcase>
以上xml配置,可完成一个CASE有N组接口,每组接口都相互有自己的入参,出参,校验策略等,相互不受影响,也可以相互依赖,相互传参,且有序。
2,校验的配置配置文件参考mybatis的配置文件,如下
<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="com.jfpointscore.dao.UserMapperXml" >
<!--校验接口一般就是2种:
1,校验接口返回的字段是否正确
2,校验接口完成请求后,落库数据是否正确
-->
<!--自定义标签,由测试编写SQL,自定义校验dubbo接口返回字段值或落库数据
id为唯一表示,group与配置中的group相关联,达到N组接口,N个SQL相互不影响,且有序
-->
<sql id="0" group="0">
select a.id as "id" from table a where a.name='张三'
</sql>
<select id="getUserList" resultMap="BaseResultMap" >
SELECT
<include refid="Base_Column_List" />
FROM tb_user
</select>
<select id="getUserById" parameterType="java.lang.Integer" resultMap="BaseResultMap" >
SELECT
<include refid="Base_Column_List" />
FROM tb_user
WHERE id = #{id}
</select>
<insert id="add" parameterType="com.jfpointscore.entity.core.User" >
INSERT INTO
tb_user
(username,age,ctm)
VALUES
(#{username}, #{age}, now())
</insert>
<update id="update" parameterType="java.util.Map" >
UPDATE
tb_user
SET
username = #{user.username},age = #{user.age}
WHERE
id = #{id}
</update>
<!--#{id} 代表传参,由于某些SQL需要DUBBO接口返回的结果作为参数,故此设计,parameterType代表参数类型等,可自定义设计
-->
<delete id="delete" parameterType="java.lang.Integer" group="0" >
DELETE FROM
tb_user
WHERE
id = #{id}
</delete>
</mapper>
3,properties文件
properties文件是属于key-value形式,用于处理一些CASE运行前后需要变更的配置
4,由于在一个CASE运行前后,可能需要做一些数据的植入和删除动作,故仿照2中的配置,自定义一套数据植入,删除的sql配置
5,参数传递问题,这是由于testng运行决定的,可自行百度。
在参数传递问题上的问题在于,以上配置有参数传递,那么代码运行完了,参数到哪里去拿?比如A接口运行完了,B接口运行完了,C接口要拿A接口的出参字段,到哪里去拿?代码已经跑完了啊?没有了啊!
我的解决方案是:
1,在CASE运行前,把所有的入参记录到临时properties文件中
2,在每一个接口运行后,把出参记录到临时properties文件中
3,每一个接口逇入参和出参都用UUID做唯一标识,则可以区分出一个接口完整的入参和出参
4,记录在临时文件中不会丢失,但是要记住有文件回收功能,不然文件会越来越大,可参考log日志框架的日志回收功能,以天为单位回收N天前的临时文件。
四阶段
提供web功能进行辅助(不详述了,就是后台管理系统)
1,需要注意,必须要把之前的逻辑提取出来,保证web的逻辑和jenkins的逻辑是一致的,这个就看代码写的好不好了
定时任务类(一般是校验落库数据和生成的文件)
分析:
1,触发定时任务之前,需要数据的植入
2,触发定时任务之前,需要触发N个相互依赖或不依赖的接口,触发接口之前,需要修改接口配置,触发完成后需要恢复配置
3,触发定时任务之前,需要修改定时任务配置
4,触发完成之后,需要恢复配置
5,触发完成后需要删除植入的数据
6,触发完成后需要校验落库数据
7,触发完成后需要校验生成文件的内容
解决方案:
1,接口部分沿用之前接口的配置,落库部分沿用之前的校验配置
2,文件部分,采用远程登录linux服务器,到文件成功路径,使用linux命令搜索文件内容
简单配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<testcase>
<!--N个命令,可查询N个文件,有序,不相关
此处仅是简化配置
-->
<!--command代表linux命令,#{sqlId}代表属性sqlId,sqlId的值代表sql配置文件中sql的sql的id,相对应,因为存在复杂情况就是文件中的内容从数据库获取,再经业务处理生成的,只能通过sql去查询数据获取-->
<group id="0">
<command>grep '#{sqlId}' /xx/xx/xxxx.txt</command>
<sqlId>0</sqlId>
</group>
<!--简单命令-->
<command id="1" group="1">
grep 'xxx' /xx/xx/xxxx.txt
</command>
<command id="2" group="2">
grep 'xxx' /xx/xx/xxxx.txt
</command>
</testcase>
当然,其中还有很多复杂配置,但是不记得了
基于这些配置,测试同学只需要按照规则,配置好配置,jenkins会自动运行代码,解析配置,进行校验,从而完成测试。
Python自动化测试视频教程:
2023最新合集Python自动化测试开发框架【全栈/实战/教程】合集精华,学完年薪40W+_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1AF411T7qJ/?spm_id_from=333.999.0.0