定向班第二期_接口测试进阶 mock 与 dubbo_20200111

schema断言

{
    "errcode": 0,
    "errmsg": "ok",
    "userid": "seveniruby1564217505.480352",
    "name": "name for testing",
    "department": [
        1
    ],
    "position": "",
    "mobile": "",
    "gender": "1",
    "email": "seveniruby1564217505.480352@testerhome.com",
    "avatar": "",
    "status": 4,
    "isleader": 0,
    "extattr": {
        "attrs": [
            
        ]
    },
    "telephone": "",
    "enable": 1,
    "hide_mobile": 0,
    "order": [
        0
    ],
    "external_profile": {
        "external_attr": [
            
        ],
        "external_corp_name": ""
    },
    "qr_code": "https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=vcc2195314e27a2be7",
    "alias": "",
    "is_leader_in_dept": [
        0
    ],
    "address": "address for testing",
    "thumb_avatar": ""
}

json schema

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "The Root Schema",
  "required": [
    "errcode",
    "errmsg",
    "userid",
    "name",
    "department"
  ],
  "properties": {
    "errcode": {
      "$id": "#/properties/errcode",
      "type": "integer",
      "title": "The Errcode Schema",
      "default": 0,
      "examples": [
        0
      ]
    },
    "errmsg": {
      "$id": "#/properties/errmsg",
      "type": "string",
      "title": "The Errmsg Schema",
      "default": "",
      "examples": [
        "ok"
      ],
      "pattern": "^(.*)$"
    },
    "userid": {
      "$id": "#/properties/userid",
      "type": "string",
      "title": "The Userid Schema",
      "default": "",
      "examples": [
        "seveniruby1564217505.480352"
      ],
      "pattern": "^(.*)$"
    },
    "name": {
      "$id": "#/properties/name",
      "type": "string",
      "title": "The Name Schema",
      "default": "",
      "examples": [
        "name for testing"
      ],
      "pattern": "^(.*)$"
    },
    "department": {
      "$id": "#/properties/department",
      "type": "array",
      "title": "The Department Schema",
      "items": {
        "$id": "#/properties/department/items",
        "type": "integer",
        "title": "The Items Schema",
        "default": 0,
        "examples": [
          1
        ]
      }
    }
  }
}

添加依赖

<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>json-schema-validator</artifactId>
      <version>4.1.2</version>
      <scope>test</scope>
</dependency>

测试用例

    @Test
    void schema_right(){
        UserApi user=new UserApi();
        user.get("seveniruby").then().body(matchesJsonSchemaInClasspath("service/user/testcase/user_get_schema_right.json"));
    }

可能为null的一些类型定义

    "name": {
      "$id": "#/properties/name",
      "default": null,
      "anyOf": [
        { "type": "string" },
        { "type": "null" }
      ],
      "title": "The Name Schema"
    },

filter机制

    @Test
    void filterAlterRequest() {
        given().filter((req, res, ctx) -> {

            //请求加密 req.getBody()
            req.queryParam("token", "xxxxx");
            req.path("/user_error.json");
            req.baseUri("http://127.0.0.1:8000");
            System.out.println(req.getURI());
            Response resReal = ctx.next(req, res);
            System.out.println(resReal.getStatusLine());
            return resReal;
        })
                .when().log().all().get("http://127.0.0.1:8000/user.json")
                .then().log().all().statusCode(200);
    }

    @Test
    void filterAlterResponse() {
        given().filter((req, res, ctx) -> {
            Response resOrigin = ctx.next(req, res);

            String bodyNew = resOrigin.getBody().asString().replace("\\"userid\\": \\"seveniruby\\",", "\\"userid\\": null,");
            ResponseBuilder responseBuilder = new ResponseBuilder().clone(resOrigin);
            responseBuilder.setBody(bodyNew);
            return responseBuilder.build();
        })
                .when().log().all().get("http://127.0.0.1:8000/user.json")
                .then().log().all().statusCode(200);
    }

异步请求

常见的特殊请求

  • 异步,第一步请求后,请求的结果需要一段时间才能输出
  • 回调,第一步请求后,被测服务会回调一个请求给调用者
  • 依赖,第一步请求后,被测服务发起请求到依赖服务器

mock

stub:真实服务的简单实现替代 https://github.com/dreamhead/moco
proxy:使用代理协议转发请求并返回真实内容 charles
fake:用假的实现代替真的实现 H2
spy:监听调用过程不做修改
mock:修改被调用方的返回
mock on stub:直接转发并修改数据 http://wiremock.org/
mock on proxy:利用代理转发并修改数据 https://github.com/lightbody/browsermob-proxy

dubbo

public class TestDubbo {
    static GreetingsService service;

    @BeforeAll
    static void beforeAll() {
        String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");

        ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
        reference.setApplication(new ApplicationConfig("first-dubbo-consumer"));
        reference.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
        reference.setInterface(GreetingsService.class);
        service = reference.get();

    }

    @ParameterizedTest
    @ValueSource(strings = {"dubbo", "seveniruby", "hogwarts"})
    void sayHi(String name){
        String message = service.sayHi(name);
        System.out.println(message);
    }
}

课后作业1

对自己公司的接口,使用schema进行校验。写出一个例子,贴代码的github地址

课间作业2

使用filter机制,解密base64加密过的接口响应内容 http://101.132.159.87:8080/user.json ,并使用jsonpath进行断言, 贴代码到回复里。

答疑

关闭