UnRAVL简介和简单使用

作者: 博客已迁移I米阳 | 来源:发表于2016-10-10 14:34 被阅读153次

UnRAVL 简介

什么是UnRAVL

UnRAVL 是一种通过编写JSON,来验证REST格式API的开源免费的自动化测试框架。
  
  github地址:https://github.com/sassoftware/unravl

JSON文件内容

通过UnRAVL定义的一些关键字(语法)来编写JSON文件,这个JSON文件的描述可以包括HTTP method,URL,HTTP Headers ,Request Body,认证AUT等。其中HTTP method 包括GET,POST,PUT,DELETE,HEAD,PATCH,为必须包括项,URL也为必须,而其它三个均为可选项目。

Paste_Image.png

UnRAVL 脚本语法

如下是从github上直接复制得到的关于UnRAVL脚本的JSON语法,如果想了解更多可以点击描述中的链接查看每个语法更详细的说明。

Syntax element. Description
{ An UnRAVL test script is a JSON object which begins with an open brace
"name" : "test name", The name of this test
"doc" : "a comment", More detailed comments/description
"template" : "template-name", Inheritance of tests via templates
"env" : {env-bindings}, Assign variables in the environment
"preconditions" : [assertions], Assert preconditions are true before calling the API
"if" : condition, Conditionally execute the test if condition is true
"headers" : {request-headers} Names/values of request headers to pass to the API
"auth" : {authentication}, Use authentication to call the API
method : "URL", The HTTP method GET, POST, PUT, DELETE, HEAD, PATCH and target URL
"body" : {body-specification} The request body (text, JSON, binary)
"bind" : [api-bindings] Bind (extract) values from the response
"assert: [assertions] Validate the response with assertions
} End of the JSON object

以下是个人对其中几个常用语法的简单认识:


Paste_Image.png

例子

编写GET请求,并对返回值做校验

  {
    "name": "Google Everest Elevation setup",
    "env": {
      "locations": "27.988056,86.925278",
      "sensor": "false",
      "url": "http://maps.googleapis.com/maps/api/elevation/json?locations={locations}&sensor={sensor}"
    },
    "doc": "Save the response to assertJson.json",
    "GET": "{url}",
    "bind": [
      {
        "doc": "save a json file"
      },
      {
        "json": "@reponseBody.json"
      },
      {
        "doc": "jsonpath"
      },
      {
        "jsonPath": {
          "actualElevation": "$.results[0].elevation",
          "actuallat": "$.results[0].location.lat",
          "actuallng": "$.results[0].location.lng"
        }
      }
    ],
    "assert": [
      {
        "status": 200
      },
      {
        "groovy": "status == 200"
      },
      {
        "headers": {
          "Content-Type": "application/json; *charset=UTF-8"
        }
      },
      {
        "json": "@assertJson.json"
      },
      "actualElevation==8815.7158203125",
      "actuallat != 0",
      "actuallng > 0",
      "actuallat != null"
    ]
  }

接口返回json:

{
  "results" : [ {
    "elevation" : 8815.7158203125,
    "location" : {
      "lat" : 27.988056,
      "lng" : 86.925278
    },
    "resolution" : 152.7032318115234
  } ],
  "status" : "OK"
}

解释:

  1. name: 用于定义该API或者Case的描述。
  2. env: 里面定义了三个变量,locations,sensor,url,其中url中还通过{locations}{sensor}来获取同样evn里面的两个变量值,最后拼接成一个完整的接口地址。
  3. doc: 因JSON文件本身不提供像其他编程语言的注释功能,所以doc关键字的提供在这里就是起到注释作用。
  4. GET: GET就是表示HTTP请求方法是GET,上面已经提到UnRAVL提供了GET外的多种请求方式,GET的对应的值{url}则表示从env中获取url对应的值地址。
    bind:里面包含多块,其中doc一样是注解作用;
      "json": "@reponseBody.json",则表示把response的body用json文件保存到该用例json文件同级目录底下;  
      jsonPath 里面则是在解析请求返回的json。
  5. assert:关键字用于做校验,这个例子尽可能的列出多种校验方式,
      其中"status": 200 表示校验请求的状态码是否为200;
      "groovy": "status == 200"则表示通过groovy语音来校验状态码(UnRAVL支持groovy和JavaScript语法);
      "headers": { "Content-Type": "application/json; *charset=UTF-8" } 表示校验接口返回的headers是否有Content-Type值为application/json; *charset=UTF-8;
      "json": "@assertJson.json"则表示response body直接跟外部文件assertJson.json对比,对比整个json文件是否一致;
      最后"actuallat != 0"等则是把bind的中jsonPath解析的结果和预期值做对比。

POST 请求

{
  "name" : "POST a hello message to httpbin",
  "env" : {
    "data1" : {
      "greeting" : "Hello, httpbin, from UnRAVL"
    }
  },
  "POST" : "http://www.httpbin.org/post",
  "headers" : {
    "Content-Type" : "text/plain",
    "Accept" : "text/plain",
    "Agent" : "UnRAVL"
  },
  "body" : {
    "json" : "data1"
  },
  "bind" : [
    {
      "json" : "@-"
    },
    {
      "groovy" : {
        "actualJson" : "responseBody.json",
        "headersJson" : "responseBody.headers"
      }
    }
  ],
  "assert" : [
    "data1 == actualJson",
    "headersJson['Accept'].textValue() == 'text/plain'",
    "headersJson['Content-Type'].textValue() == 'text/plain'",
    "headersJson['Agent'].textValue() == 'UnRAVL'"
  ]
}

接口请求返回结果:

{
  "args" : { },
  "data" : "{\"greeting\":\"Hello, httpbin, from UnRAVL\"}",
  "files" : { },
  "form" : { },
  "headers" : {
    "Accept" : "text/plain",
    "Accept-Encoding" : "gzip,deflate",
    "Agent" : "UnRAVL",
    "Content-Length" : "42",
    "Content-Type" : "text/plain",
    "Host" : "www.httpbin.org",
    "User-Agent" : "Apache-HttpClient/4.5 (Java/1.8.0_101)"
  },
  "json" : {
    "greeting" : "Hello, httpbin, from UnRAVL"
  },
  "origin" : "59.60.10.35",
  "url" : "http://www.httpbin.org/post"
}
{
  "args" : { },
  "data" : "{\"greeting\":\"Hello, httpbin, from UnRAVL\"}",
  "files" : { },
  "form" : { },
  "headers" : {
    "Accept" : "text/plain",
    "Accept-Encoding" : "gzip,deflate",
    "Agent" : "UnRAVL",
    "Content-Length" : "42",
    "Content-Type" : "text/plain",
    "Host" : "www.httpbin.org",
    "User-Agent" : "Apache-HttpClient/4.5 (Java/1.8.0_101)"
  },
  "json" : {
    "greeting" : "Hello, httpbin, from UnRAVL"
  },
  "origin" : "59.60.10.35",
  "url" : "http://www.httpbin.org/post"
}

解释:

  1. POST:表示HTTP 请求方式。
  2. heasers: 设置请求的headers值。
  3. body: 设置请求的body值,例子中获取evn中的data1的值。
  4. bind: 通过groovy关键字,表示使用groovy脚本,"responseBody.json" 获取接口请求返回的json中的叫“json”key的value值 , "responseBody.headers" 获取接口请求返回的json中的key名叫“headers”的value值。
  5. assert: 校验结果。 其中"data1 == actualJson", 用于校验接口返回的值是否与预期一致。 "headersJson['Accept'].textValue() == 'text/plain'",用于再具体解析请求返回的Json中的“headers” key中key为“Accept”的值是否为“text/plain”。

使用template

[
  {
    "name": "Google Everest Elevation setup",
    "env": {
      "url": "http://maps.googleapis.com/maps/api/elevation/json?locations=27.988056,86.925278&sensor=false"
    },
    "doc": "Save the response to GoogleEverestElevation.json",
    "GET": "{url}",
    "assert": [
      {
        "json": "@assertJson.json"
      }
    ]
  },
  {
    "name": "ThisIsATemplate.template",
    "doc": "Template which invokes the GET and asserts the response equals the contents of assertJson.json",
    "GET": "{url}",
    "assert": {
      "json": "@assertJson.json"
    }
  },
  {
    "name": "GoogleEverestElevation GET 3 use template",
    "template": "ThisIsATemplate.template"
  }
]

解释:

  1. 第一个{}内是一个完整的GET请求,并对接口返回跟assertJson.json文件做对比。
  2. 第二个name取名比较特殊:ThisIsATemplate.template这个名以.template为结尾则表示这个模块是一个template,template名为ThisIsATemplate。 模块的作用类似编程语言的公共方法,例如这个模块完成了GET请求的发起和对response整个json和assertJson.json文件的校验。
  3. 第三个name开始则表示新的Case,这个case里面"template": "ThisIsATemplate.template",则表示这个Case调用上面的template,这样这个case虽然这有name和template两个关键字但是同样完成从了GET请求的发起和结果跟外部json文件的校验。

运行

当我们编写好我们的接口Json文件后,就得考虑怎么把他们运行起来,UnRAVL 提供了多种的运行方式。

通过GUI运行

UnRAVL 提供了GUI界面来运行和调试Case。想要通过GUI方式来运行需要先下载UnRAVL包(https://github.com/sassoftware/unravl/releases),找到unravl-1.2.1.zip(目前最新版),并下载解压。得到如下目录:

Paste_Image.png

其中doc是官方帮助文档,lib是依赖的jar包。
双击打开bin文件,根据自己系统双击运行unravl.bat或者unravl.sh文件便可以打开如下GUI界面。

Paste_Image.png
  关于GUI界面的更多使用说明,可以在doc文件夹中的UI.md文件查看,或者访问https://github.com/sassoftware/unravl/blob/master/doc/ui/UI.md 查看更多
  GUI工具便于平时写Json脚本时边编写边调试使用,但是他每次只能运行一个Json文件,所以不方便我们做自动化。

通过命令行运行

除了通过GUI工具,还可以通过命令行来运行脚本,运行方式也较为简单,在下载好GUI工具包解压后,打开控制台进入到bin目录,运行:unravl.bat D:\unravl\script\getDemo.json,后面跟上需要被执行的Json文件便可。

Paste_Image.png

这种方式也是非常不方便,不建议使用。

通过Junit运行

Junit运行是比较推荐的方式,他可以批量运行多个Json,可以指定运行某个文件夹底下的所有Json文件,也可以很好的跟Jenkins结合,并生成Junit测试报告。
  想通过这种方式运行,我们需要把UnRAVL项目搭建起来,可以直接GitHub上下载工程,也可以把UnRAVL相关包引入到Java工程中。
  再新建好UnRAVL项目后,新建个java类,并添加junit的@Test方法,具体代码如下:

import com.sas.unravl.assertions.JUnitWrapper;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

public class RunScripts {

    static Map<String, Object> env() {
        Map<String, Object> env = new HashMap<String, Object>();
        return env;
    }

    @Test
    public void runScript1() {
        //  运行当个json文件
        JUnitWrapper.runScriptFiles(env(), "src/test/scripts/demo/asd.json");
    }

    @Test
    public void runFailingScripts() {
        //  运行fail文件夹下的所有json文件
        JUnitWrapper.runScriptsInDirectory(env(), "src/test/scripts/fail");
    }
}

全局变量

UnRAVL 没有全局变量的概念,但是我们平时测试又需要用到,简单说一处修改所有引用生效,例如接口需要不同的环境。 UnRAVL 提供了另一种解决方法,不过编写一个Case这里需要涉及3个json文件。
  第一个Json文件evn.json,我们用于设置“全局变量”,例如下:

{
  "name": "set environment",
  "doc": "This script is called by ../parts.son",
  "env": {
    "URL": "http://www.qa.org/post",
    "greeting":"Hello, httpbin, from UnRAVL"
  }
}

第二个Json文件caseTest.json,就是我们正常的一个Case的Json,例如下:

{
  "name": "assert environment set by env.json.",
  "doc": "This script is called by ../parts.son",
  "POST":"{URL}",
  "body":"{\"greeting\" : \"{greeting}\"}"
}

我们发现这个caseTest.json文件的POST和greeting都是取变量的,而该json却都没定义这两个参数,evn.json文件却定义了这两个变量,那两个不同的json文件如何传递变量呢?这时我们就需要用到第三个json文件。
  第三个Json文件,parts.json,具体内容如下:

[
  "@src/test/scripts/demo/env.json",
  "@src/test/scripts/demo/caseTest.json"
]

其实第三个json文件只放如需要关联的json文件。并在运行时,运行该第三个json文件便可。

与Jenkins结合

当通过Junit方式运行脚本,我们就很容易和Jenkins结合,从而达到自动构建或者每日构建等。

Jenkins Job 配置

  1. 新建一个自由风格的job


    new job
  2. 源码管理
      根据自己实际情况选择一种源码管理,例如我选用的是git,那么我只需要配置下git的一些账号密码等就可以。

源码管理
  1. 构建
      因为工程是 maven 工程,所以可以直接添加maven的构建方式(Invoke top-level Maven targets),并在Goals 中配置“clean test”,其余均可以默认
maven构建
  1. 测试报告
      Jenkins 提供了 Junit的测试报告,我们只需要在配置中的构建后操作添加Publish JUnit test result report,并设置build后生成的.xml的路径,便可。
junit report
  1. 等等
      Jenkins 还提供了如每日构建,构建失败发邮件等等的功能,可以根据自己需要配置。

简单分析

优点

  1. 简单的接口编写json文件比较容易
  2. 可以走流程
  3. 开源
  4. 扩展性良好

不足

  1. 无法与数据库交互
  2. 与拥有UI界面的自动化测试工具相比,上手难度较大
  3. 复杂接口不容易编写
  4. 小众

相关文章

网友评论

    本文标题:UnRAVL简介和简单使用

    本文链接:https://www.haomeiwen.com/subject/xbmuyttx.html