服务端测试前沿技术

知识点

服务端的API管理

https://github.com/YMFE/yapi

https://editor.swagger.io/

api规范

/pet/findByStatus:
    get:
      tags:
      - "pet"
      summary: "Finds Pets by status"
      description: "Multiple status values can be provided with comma separated strings"
      operationId: "findPetsByStatus"
      produces:
      - "application/xml"
      - "application/json"
      parameters:
      - name: "status"
        in: "query"
        description: "Status values that need to be considered for filter"
        required: true
        type: "array"
        items:
          type: "string"
          enum:
          - "available"
          - "pending"
          - "sold"
          - "hogwarts"
          default: "available"
        collectionFormat: "multi"
      responses:
        200:
          description: "successful operation"
          schema:
            type: "array"
            items:
              $ref: "#/definitions/Pet"
        400:
          description: "Invalid status value"
      security:
      - petstore_auth:
        - "write:pets"
        - "read:pets"

生成stub,方便前后端开发与QA的联调。
一个基于spring的接口stub代码

    @ApiOperation(value = "Finds Pets by status", nickname = "findPetsByStatus", notes = "Multiple status values can be provided with comma separated strings", response = Pet.class, responseContainer = "List", authorizations = {
        @Authorization(value = "petstore_auth", scopes = {
            @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
            @AuthorizationScope(scope = "read:pets", description = "read your pets")
            })
    }, tags={ "pet", })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
        @ApiResponse(code = 400, message = "Invalid status value") })
    @RequestMapping(value = "/pet/findByStatus",
        produces = { "application/xml", "application/json" }, 
        method = RequestMethod.GET)
    ResponseEntity<List<Pet>> findPetsByStatus(@NotNull @ApiParam(value = "Status values that need to be considered for filter", required = true, allowableValues = "available, pending, sold, hogwarts") @Valid @RequestParam(value = "status", required = true) List<String> status);

生成client sdk,一个是给QA生成接口测试用例,一个是给后端的人提供一个调用的sdk

    /**
     * Finds Pets by status
     *
     * Multiple status values can be provided with comma separated strings
     *
     * @throws ApiException
     *          if the Api call fails
     */
    @Test
    public void findPetsByStatusTest() throws ApiException {
        List<String> status = Arrays.asList("sold");
        List<Pet> response = api.findPetsByStatus(status);
        assertEquals(response.get(0).getName() , "xx");

        // TODO: test validations
    }

MockServer与Mock相关的概念


服务端的测试用例生成

mustache模板技术
https://mustache.github.io/

https://github.com/swagger-api/swagger-codegen

java测试用例生成

流量复制与Diff测试

网络协议层的请求构造工具
https://github.com/buger/goreplay

代理层面的twitter diffy
https://github.com/opendiffy/diffy

hook层的请求构造工具
https://github.com/alibaba/jvm-sandbox-repeater

RPC协议的测试

rpc测试用例结构

  • page/api object模式的定义接口文件(po的接口定义) PetApiInterface
  • po方法具体实现(http rpc) PetApiRPCImplemented PetApiImplemented
  • 测试用例文件 PetApiTest

https://developers.google.com/protocol-buffers/docs/javatutorial

https://github.com/apache/thrift/tree/master/tutorial/java

RPC:可以基于不同的协议实现, 比如http、json rpc、tcp、udp协议实现。最后调用的时候是协议透明,只需要调用特定语言的sdk就可以。

diffy是不是可以理解成在同一个执行环境,先用 master分支执行request后记录response,然后在预发布分支执行同样的request后记录response,两者做对比?

master candidate代表分支,也代表环境,是不同的环境上运行着不同的分支代码。

master分支运行在2个环境上,主环境和副本环境。candidate分支运行在预发布环境上或者测试环境上