自动化框架的设计与实现

server/2025/3/31 11:09:38/
一、自动化测试框架

在大部分测试人员眼中只要沾上“框架”,就感觉非常神秘,非常遥远。大家之所以觉得复杂,是因为落地运用起来很复杂;每个公司,每个业务及产品线的业务流程都不一样,所以就导致了“自动化测试框架”去完成自动化测试的时候产生很多不稳定因素,这样就很难定位成一个固定的框架。其实不然,真正的自动化测试框架不是一个模式,而是一种思想和方法的集合,通俗的讲就是一个架构。

二、自动化测试框架思想

为了更好的了解自动化测试框架,我们先从自动化测试的发展历程说起;一般测试工作限在3年以上且接触过自动化测试的应该对以下几种自动化测试框架思想有一定的认知:

  • 模块化思想
  • 库思想
  • 数据驱动思想
  • 关键字驱动思想

以上仅仅是代表了一种自动化测试的思想,并不能定义为框架。上面讲到框架=思想+方法,于是演化了以下五种框架:

1、模块化测试脚本框架

需要创建小而独立的可以描述的模块、片断以及待测应用程序的脚本。这些树状结构的小脚本组合起来,就能组成能用于特定的测试用例的脚本。

2、测试库框架

与模块化测试脚本框架很类似,并且具有同样的优点。不同的是测试库框架把待测应用程序分解为过程和函数而不是脚本。这个框架需要创建描述模块、片断以及待测应用程序的功能库文件。

3、关键字驱动或表驱动的测试框架

这个框架需要开发数据表和关键字。这些数据表和关键字独立于执行它们的测试自动化工具,并可以用来“驱动"待测应用程序和数据的测试脚本代码,关键宇驱动测试看上去与手工测试用例很类似。在一个关键字驱动测试中,把待测应用程序的功能和每个测试的执行步骤一起写到一个表中。

这个测试框架可以通过很少的代码来产生大量的测试用例。同样的代码在用数据表来产生各个测试用例的同时被复用。

4、数据驱动测试框架

在这里测试的输入和输出数据是从数据文件中读取(数据池,ODBC源,CSV文件,EXCEL文件,Json文件,Yaml文件,ADO对象等)并且通过捕获工具生成或者手工生成的代码脚本被载入到变量中。在这个框架中,变量不仅被用来存放输入值还被用来存放输出的验证值。整个程序中,测试脚本来读取数值文件,记载测试状态和信息。这类似于表驱动测试,在表驱动测 试中,它的测试用例是包含在数据文件而不是在脚本中,对于数据而言,脚本仅仅是一个“驱动器”,或者是一个传送机构。然而,数据驱动测试不同于表驱动测试,尽管导航数据并不包含在表结构中。在数据驱动测试中,数据文件中只包含测试数据。

5、混合测试自动化框架

最普遍的执行框架是上面介绍的所有技术的一个结合,取其长处,弥补其不足。这个混合测试框架是由大部分框架随着时间并经过若干项目演化而来的。

三、接口自动化测试框架策略
  1. 设计出来的框架是直接给测试人员,而且其他的测试人员只需要简单的向里面不断的补充测试用例即可;所以我们的框架设计必须三简化即操作简单,维护简单,扩展简单。
  2. 设计框架的同时一定要结合业务流程,而且不仅仅靠技术实现,其实技术实现不难,难点对业务流程的理解和把握。
  3. 设计框架时要将基础的封装成公用的,如:get请求、post请求和断言封装成同基础通用类。
  4. 测试用例要与代码分享,这样便于用例管理,所以将我们选择上面的数据驱动思想。
四、接口自动化测试框架设计
1、进行接口框架设计前,我们先看看当前的一些主流接口自动化工具框架

2、以上各工具特性

根据以上的特性可得我们优先考虑Python+Requests和HttpRunner;下面我们根据其两个框架分别来分析下用例执行过程。

3、用例执行解析

Python的Requests库针对所有的HTTP请求方法,采用的是统一的接口

requests.request(method, url, **kwargs)

其中,kwargs可以保护HTTP请求所有可能用到的信息,例如:headers、cookies、params、data、auth等。所以,只要遵循Requests的参数规范,在接口测试用例中复用Requests参数的概念即可。而HttpRunner处理逻辑很简单,直接读取测试用例中的各项参数,传递给Requests发起请求。

1)Requests接口请求示例

 
  1. def test_login(self):

  2. url = "www.xxx.com/api/users/login"

  3. data = {

  4. "name": "user1",

  5. "password": "123456"

  6. }

  7. resp = requests.post(url, json=data)

  8. self.assertEqual(200, resp.status_code)

  9. self.assertEqual(True, resp.json()["success"])

在该用例中,实现了HTTP POST请求,然后对响应结果进行判断,检查响应code等是否符合预期。

这样的用例在实际项目中会存在两个问题:

  • 用例模式基本固定,会存在大量相似或重复的用例,用例维护有很大问题
  • 用例与执行代码不分离,参数数据也未分离,同样不易维护

2)HttpRunner使用json/yaml格式处理测试用例,分离后的用例描述如下

 
  1. {

  2. "name": "test login",

  3. "request": {

  4. "url": "www.xxx.com/api/users/login",

  5. "method": "POST",

  6. "headers": {

  7. "content-type": "application/json"

  8. },

  9. "json": {

  10. "name": "user1",

  11. "password": "123456"

  12. }

  13. },

  14. "response": {

  15. "status_code": 200,

  16. "headers": {

  17. "Content-Type": "application/json"

  18. },

  19. "body": {

  20. "success": true,

  21. "msg": "user login successfully."

  22. }

  23. }

  24. }

3)HttpRunner用例执行引擎

 
  1. def run_testcase(testcase):

  2. req_kwargs = testcase['request']try:

  3. url = req_kwargs.pop('url')

  4. method = req_kwargs.pop('method')

  5. except KeyError:

  6. raise exception.ParamsError("Params Error")

  7. resp_obj = requests.request(url=url, method=method, **req_kwargs)

  8. diff_content = utils.diff_response(resp_obj, testcase['response'])

  9. success = False if diff_content else True

  10. return success, diff_content

4)从测试用例中获取HTTP接口请求参数,testcase['request']

 
  1. {

  2. "url": "www.xxx.com/api/users/login",

  3. "method": "POST",

  4. "headers": {

  5. "content-type": "application/json"

  6. },

  7. "json": {

  8. "name": "user1",

  9. "password": "123456"

  10. }

  11. }

5)发起Http请求

requests.request(url=url, method=method, **req_kwargs)

6)检测测试结果,即断言

utils.diff_response(resp_obj, testcase['response'])
五、接口自动化测试框架落地

根据简单易用易维护原则我们使用HttpRunner工具设计框架。

1、HttpRunner简介

主要特性:

  • 集成了Requests的全部特性,满足对http、https的各种测试需求
  • 测试用例与代码分离,采用YAML/JSON的形式描述测试场景,保障测试用例具备可维护性
  • 测试用例支持参数化和数据驱动机制
  • 基于 HAR 实现接口录制和用例生成功能
  • 结合 Locust 框架,无需额外的工作即可实现分布式性能测试
  • 执行方式采用 CLI 调用,可与 Jenkins 等持续集成工具完美结合
  • 测试结果统计报告简洁清晰,附带详尽统计信息和日志记录
  • 具有可扩展性,便于扩展实现 Web 平台化

2、环境准备

安装HomeBrew(MacOs软件包管理工具,类似apt-get、yum)

  • 终端执行
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • 安装pyenv并配置环境变量:python版本管理器,可同时管理多个Python版本(HttpRunner是基于Python开发,但是支持Python3.6.0以上)
 
  1. brew install pyenv

  2. echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile

  3. echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile

  4. echo 'eval "$(pyenv init -)"' >> ~/.bash_profile

  5. exec $SHELL -l

  • 安装Python3.6
 
  1. pyenv install --list //查看可安装的Python版本

  2. pyenv install 3.6.0 //安装3.6.0版本

  3. pyenv rehash //更新pyenv

  4. pyenv versions //查看已经安装的python版本,带*号的是当前使用的版本

  • 选择Pyhton
pyenv global 3.6.0 //设置全局版本,即当前系统使用的版本将切换为3.6.0
  • 安装HttpRunner并校验
 
  1. pip install httprunner

  2. //运行如下命令,若正常显示版本号,则说明httprunner安装成功:

  3. hrun -V

  4. 0.9.8

至此HttpRunner已搭建完成

3、用例管理

在HttpRunner中,测试用例引擎最大的特色就是支持Yaml/Json格式的用例描述形式;

采用YAML/JSON格式编写维护测试用例,优势还是很明显的:

  • 相比于表格形式,具有更加强大的灵活性和更丰富的信息承载能力;
  • 相比于代码形式,减少了不必要的编程语言语法重复,并最大化地统一了用例描述形式,提高了用例的可维护性。

Yaml格式

Json格式

以下以数澜--数栖平台2.X中的研发平台为例(采取Json格式)

场景:项目空间后,需要快速支持创建Demo示例,即自动创建各种目录和任务。

1)确定业务流程所使用到的接口并通过Postman或Jmeter调试通过及分好类

  • 查询类(Get请求)接口:查询任务目录、查询资源组、查询工作流等
  • 新增类(Post请求)接口:新建目录、新建任务等

2)根据业务流程确定接口顺序

  • 如要在某个目录下新建任务:则先要调用新建目录接口再调用作建任务接口

3)向Json文件里按照规则填写接口相关信息

  • 接口Base_Url
  • 接口路径
  • 接口请求方式
  • 接口请求参数
  • 接口断言
  • 接口返回参数(关联接口时会用到上一接口返回的参数)

以下是部分用例示例

4)用例填写完成后,执行用例文件,如Json文件为task.json

hrun task.json

5)查看运行结果

  • 在此目录下会自动生成一个reports文件,进入该文件夹可看到生成带时间的html(执行一次就会生成一个Html文件)

 打开此Html查看

全部通过

部分通过

  • 点击Log,可查看具体请求信息和返回信息

 点击trackback可查看定位错误信息


http://www.ppmy.cn/server/179790.html

相关文章

Git+Fork 入门介绍

git 分区理解 fork安装 从路径下去拿软件时,注意先拉到本地。经验来看,fork直接安装会出不可思议的问题。 fork操作 安装,注意设置好名字,如果之前安装的同学,名字没有写好,重新安装设置好名字。 clone操…

Elasticsearch 之 ElasticsearchRestTemplate 普通查询

前言: 上一篇我们分享了 Spring Boot 整合 Elasticsearch 使用 ElasticsearchRepository 完成简单的增删改查,我们发现 ElasticsearchRepository 中很多稍微复杂一些的查询就会显示方法过期,对于 Elasticsearch 7.X 版本,我们可以…

React企业级复杂搜索方案深度实战

一、高阶搜索架构设计 1.1 分层架构模式 // 核心分层结构 src/ ├─ features/ │ ├─ search/ │ │ ├─ api/ // API通信层 │ │ ├─ domain/ // 领域模型 │ │ ├─ hooks/ // 业务逻辑Hook │ │ ├─ components/ //…

RT-Thread CI编译产物artifacts自动上传功能介绍

近期在RT-Thread开源项目中,我们引入了一项实用的功能改进——将每次CI(持续集成)编译生成的产物(artifacts)自动上传到GitHub,方便开发者和用户能够更便捷地获取和测试最新的编译结果。 参考链接&#xf…

春日焕新居:约克VRF中央空调,科技赋能,带你开启健康呼吸新时代

春回大地,万物复苏的季节里,无数家庭怀揣美好憧憬之心开启家居焕新装修。然而,当精心挑选的建材逐渐构筑起理想家的雏形,往往伴随着甲醛等有害气体的困扰,如同一道无形的屏障,阻挡我们对健康家居生活的追求。别担心,约克VRF中央空调凭借其卓越的产品性能和服务,为您打造一个健康…

HTTP 1.0和2.0 有什么区别?

HTTP 1.0和HTTP 2.0是互联网中用于数据传输的重要协议,两者在功能和性能上有显著差异。 以下是它们的主要区别: HTTP 1.0 的特点: 单一连接:每个请求需要独立连接,导致高延迟和资源浪费。文本传输:使用文…

【更新中】【React】基础版React + Redux实现教程,自定义redux库和react-redux库

本项目是一个在react中,使用 redux 管理状态的基础版实现教程,用简单的案例练习redux的使用,旨在帮助学习 redux 的状态管理机制,包括 store、action、reducer、dispatch 等核心概念。 项目地址:https://github.com/Yv…

批量给 PDF 页面添加超链接

让我们的 PDF 文档上传到互联网的时候,我们可能需要对其做一些处理,比如说我们希望别人在点击 PDF 文档页面的时候就跳转到指定的链接,那我们就需要给 PDF 文档的页面上添加链接。今天就给大家介绍一下如何同时对多个 PDF 文档的所有页面添加…