一,har简介
- Har格式是指HTTP归档格式(HTTP Archive Format)。
- 用于记录HTTP会话信息的文件格式。
- 多个浏览器都可以生成 Har 格式的数据。
二,har应用场景
- 通过 Har 格式的接口数据,转换为接口自动化测试脚本:
- 提升脚本的编写效率
- 降低脚本的出BUG的几率
 
三,实现思路

四,模板技术
- Mustache是一种轻量级的模板语言。
- 需要定义模板,然后可以将数据填充到设定好的位置。
- 官网地址:https://mustache.github.io/
- 环境安装:
<!-- 模版相关库 -->
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.9.10</version>
</dependency>
五,模板技术代码实现
- 首先定义一个模板,在Resources文件夹下新建一个hogwarts.template模板文件,并定义文件内容
Hello,my name is {{name}}, age is {{age}}
- 使用模板代码
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
public class MuxstacheExample {
    public void mustacheTest(){
        Map<String, String> data = new HashMap<>();
        data.put("name","demi");
        data.put("age", "28");
        //初始化并读取模板文件中的内容
        DefaultMustacheFactory mustacheFactory = new DefaultMustacheFactory();
        Mustache mustache = mustacheFactory.compile("hogwarts.template");
        //将数据进行替换
        StringWriter writer = new StringWriter();
        try {
            mustache.execute(writer,data).flush();
            //将替换后的数据进行打印
            System.out.println(writer.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
- 新建一个测试类,验证是否成功
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class MuxstacheExampleTest {
    @Test
    void mustacheExample() {
        MuxstacheExample muxstacheExample = new MuxstacheExample();
        muxstacheExample.mustacheTest();
    }
}
六, har 生成用例
(1) 提前准备测试用例模版。
常用模板:
- junit5模板
 // java 接口测试用例
package com.ceshiren.har;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
public class HttpbinTest {
    @Test
    void httpbinReq() {
        given()
                // 可以设置测试预设
                .when()
                // 发起 GET 请求
                .get("{{url}}")
                .then()
                // 解析结果
                .log().all()  // 打印完整响应信息
                .statusCode(200);  // 响应断言
    }
}   
- httpRunner模板
# httprunner 的用例模版
config:
    name: basic test with httpbin
teststeps:
-
    name: httprunner的模板
    request:
        url: {{url}}
        method: GET
    validate_script:
        - "assert status_code == 200"
- pytest模板
# python 接口测试用例
import requests
def test_request():
    r = requests.get(url="{{url}}")
(2)将需要读取的接口返回数据转换成har格式并保存
- 
浏览器打开开发者模式,请求接口栏点击右键,选择复制 - 选择复制数据为Har格式。 
 
- 
新建har文件,将复制的数据存放到resources文件夹下 
 
(3) 将读取的Har数据写入到模板中。
import com.alibaba.fastjson.JSONPath;
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class GenerateCase {
    // 从Har 文件中读取数据。
    public  Map<String, String> loadHar(String filePath){
        Map<String,String> reqData = new HashMap<>();
        try {
            DocumentContext context = JsonPath.parse(new File(filePath));
            ArrayList<String> harUrl =  context.read("$..request.url");
//            System.out.println(harUrl);
            reqData.put("url",harUrl.get(0));  
        } catch (IOException e) {
            e.printStackTrace();
        }
        return reqData;
    }
    // 根据模板生成测试用例,testCaseFileName为需要生成的测试用例文件地址
    public void writeCaseByTemplate(String originTemplate,String testCaseFileName, String harFileName) throws IOException {
        Map<String,String> reqData = loadHar(harFileName);
        //  初始化并读取模板文件中的内容并进行编译
        DefaultMustacheFactory mustacheFactory = new DefaultMustacheFactory();
        Mustache mustache = mustacheFactory.compile(originTemplate);
        //  定义一个文件
        File outFile = new File(testCaseFileName);
        try {
            //  将数据写入到文件中
            PrintWriter printWriter = new PrintWriter(outFile);
            //将模板中的url进行替换
            mustache.execute(printWriter,reqData).flush();
            printWriter.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
(4) 生成测试用例
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.*;
class GenerateCaseTest {
    @Test
    void loadHar() {
        GenerateCase generateCase = new GenerateCase();
        System.out.println(generateCase.loadHar("src/main/resources/httpbin.ceshiren.com.har"));
    }
    @Test
    void writeCaseByTemplate() throws IOException {
        GenerateCase generateCase = new GenerateCase();
        generateCase.writeCaseByTemplate("src/main/resources/junit.template",
                "src/test/java/har/httpbinTest.java",
                "src/main/resources/httpbin.ceshiren.com.har");
    }
    @Test
    //httpRunner生成的用例文件名称是以yaml结尾的
    void writeCaseByTemplateHttpRunner() throws IOException {
        GenerateCase generateCase = new GenerateCase();
        generateCase.writeCaseByTemplate("src/main/resources/httpRunner.template",
                "src/test/java/har/test_httpbin.yaml",
                "src/main/resources/httpbin.ceshiren.com.har");
    }
    @Test
        //pytest生成的用例文件名称是以py结尾的
    void writeCaseByTemplateHttpPyTest() throws IOException {
        GenerateCase generateCase = new GenerateCase();
        generateCase.writeCaseByTemplate("src/main/resources/pytest.template",
                "src/test/java/har/test_httpbin.py",
                "src/main/resources/httpbin.ceshiren.com.har");
    }
}

