接口加解密与多套测试环境

加密解密简介

  • 加密:明文转换成密文的过程
  • 解密:密文还原成明文的过程
  • 常见加密算法
    • AES
    • RSA
    • MD5
    • Base64

解密方案

  • 通用加密算法
    • 使用对应解密算法
  • 自研加密算法
    • 研发提供加解密 lib
  • 第三方加密服务
    • 寻求加密方提供远程解析服务

Base64 加解密

  • 加密
    • Base64.encodeBase64String()
  • 解密
    • Base64.decodeBase64()

示例源码

package com.vernon.base64;

import com.jayway.jsonpath.JsonPath;
import io.restassured.http.ContentType;
import org.apache.commons.codec.binary.Base64;
import org.junit.jupiter.api.Test;

import java.nio.charset.StandardCharsets;

import static io.restassured.RestAssured.given;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertAll;

public class TestBase64 {

    @Test
    void testBase64() {

        // 定义一个明文字符串
        String str = "hogwarts";

        // 将字符串转换成字节数组
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);

        // 对明文字符串对应的字节数组 使用 Base64.encodeBase64String() 完成 Base64 加密
        String encodeStr = Base64.encodeBase64String(bytes);
        System.out.println(encodeStr);

        String jsonStr = given()
                        .contentType(ContentType.URLENC)
                        .formParams("msg", encodeStr)
                .when()
                        .post("https://httpbin.org/post")
                .then()
                        .statusCode(200)
                        .extract().response().getBody().asString();

        // 提取接口响应的密文
        String encodeMsg = JsonPath.read(jsonStr, "$.form.msg");

        // 对密文使用 Base64.decodeBase64() 完成 Base64 解密
        byte[] arr = Base64.decodeBase64(encodeStr);
        String decodeStr = new String(arr, StandardCharsets.UTF_8);

        // 对响应字段完成断言
        assertAll(
                () ->  assertThat(decodeStr,equalTo("hogwarts"))
        );

    }
}

多套环境测试背景

  • 集成测试环境
  • 验收测试环境
  • 灰度测试环境

多套环境测试解决方案

最佳实践:配置文件

Jackson 依赖

  • jackson-databind
  • jackson-dataformat-yaml
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-yaml</artifactId>
    <version>2.13.0</version>
</dependency>

实现源码

package com.vernon.envs;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.restassured.RestAssured;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Objects;

import static io.restassured.RestAssured.given;

public class TestEnvsYaml {

    @BeforeAll
    static void beforeAll() throws IOException {
        /*
           使用 Jackson 读取 yaml 读取文件
         */
        // 示例化一个 ObjectMapper 对象
        ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());

        // 读取 resources 目录中的 envs.yaml 配置文件
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        File yamlFile = new File(Objects.requireNonNull(contextClassLoader.getResource("envs.yaml")).getFile());

        // 定义序列化结构 TypeReference<>()
        TypeReference<HashMap<String,String>> typeRef = new TypeReference<HashMap<String, String>>() {};

        // 解析 envs.yaml 文件内容,并指定 返回内容为 定义序列化结构 typeRef
        HashMap<String, String> envs = yamlMapper.readValue(yamlFile, typeRef);

        // 设定基线域名地址为 选定的域名地址
        RestAssured.baseURI = envs.get(envs.get("default"));

    }

    @Test
    void testEnvsYaml() {
        // 发起请求
        given()
        .when()
                .get("/get")
        .then()
                .log().all()
                .statusCode(200);
    }

}

envs.yaml

  • 文件路径
src/test/resources/envs.yaml
  • 文件内容
default: org
org: https://httpbin.org
ceshiren: https://httpbin.ceshiren.com

多响应类型封装设计

xml 转换 dict(Python)

  • 环境准备: pip install xmltodict
  • 依赖包版本: 0.13
  • 示例源码
import json
import xmltodict
import requests

def test_xml_res():
    """
    xml转换为json
    :return:
    """
    res = requests.get("https://www.nasa.gov/rss/dyn/lg_image_of_the_day.rss")
    dict_res = xmltodict.parse(res.text)

xml 转换 json (Java)

  • 将 xml 转换成字符串 json 依赖
<!-- 直接将xml转换成字符串json -->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.13.0</version>
</dependency>
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.6.0</version>
    <scope>test</scope>
</dependency>
  • 实现源码
package com.vernon.mulity_res_to_json;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;
import org.junit.jupiter.api.Test;

import java.io.IOException;

import static io.restassured.RestAssured.given;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertAll;

public class MulitiResToJsonTest {


    public String mulitiResToJson(String originRes) {

        if (originRes.startsWith("<?xml")) {
            XmlMapper xmlMapper = new XmlMapper();
            try {
                JsonNode node = xmlMapper.readTree(originRes.getBytes());
                ObjectMapper jsonMapper = new ObjectMapper();
                originRes = jsonMapper.writeValueAsString(node);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return originRes;
    }

    @Test
    public void mulitiResToJsonTest(){

        String xmlResBody = given()
                .when()
                        .get("https://www.nasa.gov/rss/dyn/lg_image_of_the_day.rss")
                .then()
                        .statusCode(200)
                        .extract().response().getBody().asString();

        String jsonRes = mulitiResToJson(xmlResBody);
        JSONArray read = JsonPath.read(jsonRes, "$..title");
        assertAll(
                () -> assertThat(read.get(0),equalTo("NASA Image of the Day"))
        );

    }

}