前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SoapUI系列|项目实战

SoapUI系列|项目实战

作者头像
测试邦
发布2019-07-24 11:33:44
1.3K0
发布2019-07-24 11:33:44
举报
文章被收录于专栏:测试邦测试邦测试邦

XXXweb系统的api测试(http request方式实现)

1.明确待测试api的来源

笔者工作中是项目api来源为jira-confluence,研发哥哥会把api接口的详细定义写到confluence上

在使用soapui测试工具编写测试api时,所有跟api有关的信息全部为confluence为准绳。

2 详细解析

2.1登录api

笔者这里就列举了三个常用登录测试case来测试登录api

2.1.1输入正确的登录信息

2.1.2断言

返回状态码断言:

返回信息头断言:(脚本断言)

脚本源码如下:(脚本语言选择groovy)

脚本代码如下:

def response = messageExchange.modelItem.testCase.testSteps["登录成功"].testRequest.response;

//获取服务器响应

def headers = response.responseHeaders;

//定义服务器响应头

def server = headers.get("Server").toString().replace("[","").replace("]","");

//获取服务器响应头中的server属性值,并且转成string数据类型,去掉“[”和“]”,否则校验通不过

def date = headers.get("Date").toString().replace("[","").replace("]","");

def contentlength = headers.get("Content-Length").toString().replace("[","").replace("]","");

def connection = headers.get("Connection").toString().replace("[","").replace("]","");

def SetCookie = headers.get("Set-Cookie").toString().replace("[","").replace("]","");

def expect_server = "nginx"

def expect_connection = "keep-alive"

def expect_contentlength = "0"

assert server == expect_server, "服务器返回server地址和预期地址不符合!"

//做断言,server值和预期值相等,否则报错“服务器返回server地址和预期地址不符合!”

assert connection == expect_connection, "服务器返回connection地址和预期地址不符合!"

assert contentlength == expect_contentlength, "服务器返回contentlength和预期不符合!"

2.1.3添加脚本step,设置工程全局变量ticket

脚本源码如下:

// 获取登录的ticket

def response = testRunner.testCase.getTestStepByName("登录成功").httpRequest.response;

def header = response.responseHeaders;

def cookies = header.get("Set-Cookie");

testRunner.testCase.testSuite.project.setPropertyValue("ticket", cookies.toString());

//添加project级变量ticket

2.1.4给测试工程下所有的api请求添加正确的http信息头

  1. 选中测试工程
  2. 选择Events ---tab页面

3.添加完成后选择作用范围

Target可以指定某个teststep,如图:

*如果要在工程中所有的api请求前都添加event handler默认target为空即可

  1. Evnet Hnadler脚本详解

脚本源码:

// 描述:处理请求头

def headers = request.requestHeaders;

log.info(context.expand( '${#Project#ticket}' ))

// 携带用户信息

// 获取方法

def method = request.getMethod().toString().toLowerCase();

// 获取提交的数据类型

def mediaType = request.getMediaType().toString().toLowerCase();

log.info(mediaType)

// API约定:不是表单提交,就是json格式提交

if (mediaType != 'multipart/form-data') {

request.setMediaType('application/json');

headers.remove("Content-Type");

headers.put("Content-Type", "application/json; charset=UTF-8");

headers.remove("Accept");

headers.put("Accept", "application/json");

}

headers.remove("Cookie");

headers.put("Cookie", context.expand( '${#Project#ticket}' ));

request.requestHeaders = headers;

2.2 Exercise相关api测试

2.2.1 add

1. 获取新增习题id

2.在groovy script step中右键

3.调试:使用log.info()方法

验证OK。

4.把exercise_id添加到project的Property中

5.添加JDBC链接:获取数据库中exercise表中最新的id值(id是自增长,最新id值和服务器返回的id值相等则通过验证)

笔者用的是MySQL数据库,配置如下:

注意:把第一章第一节中下载的mysql的jar包放在如下位置:

6.添加Assertion Step

配置如下:

2.2.2 view

1使用新增习题id参数化查看系统api的请求参数(将添加习题的id作为查看习题的请求id)

这样做同样有优缺点。

优点:后面的编辑和删除api接口可以同样调用该参数,这样可以重复对增删改查api接口进行重复测试,这是使用固定参数达不到的

缺点:api的测试有了耦合,如果新增接口失败会导致其他的接口跟着失败,跟实际情况不符

建议还是使用参数化方式,参数化方式更适合api的持续集成测试

2.返回值断言(脚本断言)共四步

第一步:定义预期结果

在定义预期结果前,我们先引入groovy中处理json解析器:JsonSlurper

源码如下:

//引入groovy中处理json解析器

import groovy.json.JsonSlurper;

//引用messageExchange对象包获取服务器返回的json字符串

def response=messageExchange.modelItem.testCase.testSteps["view"].testRequest.response.contentAsString;

//log.info(response);

//新建一个json解析器

def slurper=new JsonSlurper();

//把json结构解析成字符串的表达形式

def result=slurper.parseText(response);

OK我们完成了groovy中的json解析器的引入,开始预期结果的定义,源码如下:

def expect_exercise_id = context.expand( '${#Project#exercise_id}' )

def expect_exercise_content = "正常的单选题习题题干"

def expect_exercise_knowledge_point = "正常的单选题习题知识点"

def expect_exercise_analysis_content = "习题分析"

def expect_exercise_tags_id = 1

def except_exercise_tags_name = "企业职能"

def except_exercise_answers_content_1 = "选项A"

def except_exercise_answers_content_2 = "选项B"

def except_exercise_answers_content_3 = "选项C"

def except_exercise_answers_content_4 = "选项D"

def except_exercise_answers_exerciseId_1 = context.expand( '${#Project#exercise_id}' )

def except_exercise_answers_exerciseId_2= context.expand( '${#Project#exercise_id}' )

def except_exercise_answers_exerciseId_3 = context.expand( '${#Project#exercise_id}' )

def except_exercise_answers_exerciseId_4 = context.expand( '${#Project#exercise_id}' )

def except_exercise_answers_is_right_1 = "选项A"

def except_exercise_answers_is_right_2 = "选项B"

def except_exercise_answers_is_right_3 = "选项C"

def except_exercise_answers_is_right_4 = "选项D"

除了和id相关的预期结果定义为变量,其他的预期结果我们定义为常量

第二部:解析json字符串得到实际结果

//定义实际结果

def actual_exercise_id = result.id

def actual_exercise_content = result.content

def actual_exercise_knowledge_point = result.knowledge_point

def actual_exercise_analysis_content = result.analysis.content

def actual_exercise_tags_id = result.tags.id

def actual_exercise_tags_name =result.tags.name

def actual_exercise_answers_content_num = result.answers.content.size

def actual_exercise_answers_content_1 = result.answers.content[0]

def actual_exercise_answers_content_2 = result.answers.content[1]

def actual_exercise_answers_content_3 = result.answers.content[2]

def actual_exercise_answers_content_4 = result.answers.content[3]

def actual_exercise_answers_exerciseId_1 = result.answers.exerciseId[0]

def actual_exercise_answers_exerciseId_2= result.answers.exerciseId[1]

def actual_exercise_answers_exerciseId_3 = result.answers.exerciseId[2]

def actual_exercise_answers_exerciseId_4 = result.answers.exerciseId[3]

def actual_exercise_answers_is_right_1 = result.answers.is_right[0]

def actual_exercise_answers_is_right_2 = result.answers.is_right[1]

def actual_exercise_answers_is_right_3 = result.answers.is_right[2]

def actual_exercise_answers_is_right_4 = result.answers.is_right[3]

第三部:写断言

这里就不把所有的断言都写完了,例子如下:

assert expect_exercise_id == actual_exercise_id, "习题的id错误!"

assert expect_exercise_content == actual_exercise_content, "习题的content错误!"

assert expect_exercise_knowledge_point == actual_exercise_knowledge_point, "习题的knowledge_point错误!"

assert expect_exercise_analysis_content == actual_exercise_analysis_content,"答案解析内容错误!"

assert except_exercise_answers_content_num == actual_exercise_answers_content_num,"答案数量错误!"

第四部:调试脚本

运行测试脚本,结果如图:

处理方式1:把log.info(conents)注释掉,再运行,结果如下:

已经不是脚本本身的问题了,而是断言没有通过。

再看这个断言问题:

看上去这两个值好像是相等的,为什么断言还没有通过呢?

我们先看看这两个值的类型,是否都是integer类型

使用:

运行测试,结果如下:

expect_exercise_id是string类型,actual_exercise_id是integer类型,所以这两个值肯定是不相等的,就需要进行类型转换,我们这里把expect_exercise_id转成ingteger类型,再运行测试:

Id的断言测试已经通过了。

3 Jenkins持续集成

在第一章环境搭建中已经详细说明了jenkins的搭建过程,不再陈述,访问jenkins配置页面,进入研发人员创建的job(构建待测程序的job中),如图:

增加构建后步骤为:Build other projects,在要构建的项目中输入soapui的测试job:

选择在成功构建后触发soapui的测试job

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试邦 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
持续集成
CODING 持续集成(CODING Continuous Integration,CODING-CI)全面兼容 Jenkins 的持续集成服务,支持 Java、Python、NodeJS 等所有主流语言,并且支持 Docker 镜像的构建。图形化编排,高配集群多 Job 并行构建全面提速您的构建任务。支持主流的 Git 代码仓库,包括 CODING 代码托管、GitHub、GitLab 等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档