golang HTTP(S)代理录制与模拟REST/SOAP API插件库hoverfly的使用
Golang HTTP(S)代理录制与模拟REST/SOAP API插件库Hoverfly的使用
API开发与测试的模拟工具
Hoverfly是一个轻量级的开源API模拟工具。使用Hoverfly,您可以创建应用程序依赖的API的真实模拟。
主要特性:
- 用真实、可重复使用的模拟替换缓慢、不稳定的API依赖
- 模拟网络延迟、随机故障或速率限制以测试边缘情况
- 使用任何编程语言进行扩展和定制
- 导出、共享、编辑和导入API模拟
- 提供Java原生语言绑定
- REST API支持
- 轻量级、高性能、可在任何地方运行
- Apache 2许可证
Golang中使用Hoverfly的完整示例
下面是一个在Golang中使用Hoverfly进行API录制和模拟的完整示例:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os/exec"
"time"
)
func main() {
// 1. 启动Hoverfly作为代理服务器
startHoverfly()
// 2. 录制模式示例
recordModeExample()
// 3. 模拟模式示例
simulateModeExample()
}
func startHoverfly() {
// 启动Hoverfly进程
cmd := exec.Command("hoverfly", "-pp", "8500", "-ap", "8888")
err := cmd.Start()
if err != nil {
fmt.Println("启动Hoverfly失败:", err)
return
}
// 等待Hoverfly启动
time.Sleep(2 * time.Second)
fmt.Println("Hoverfly已启动")
}
func recordModeExample() {
// 设置Hoverfly为录制模式
resp, err := http.Get("http://localhost:8888/api/v2/hoverfly/mode?mode=record")
if err != nil {
fmt.Println("设置录制模式失败:", err)
return
}
defer resp.Body.Close()
fmt.Println("Hoverfly已设置为录制模式")
// 通过Hoverfly代理发送请求
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL("http://localhost:8500"),
},
}
// 发送请求到真实API(通过Hoverfly代理)
resp, err = client.Get("https://jsonplaceholder.typicode.com/posts/1")
if err != nil {
fmt.Println("请求失败:", err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("录制模式响应:", string(body))
// 导出录制的请求/响应对
resp, err = http.Get("http://localhost:8888/api/v2/simulation")
if err != nil {
fmt.Println("导出模拟失败:", err)
return
}
defer resp.Body.Close()
simulation, _ := ioutil.ReadAll(resp.Body)
fmt.Println("录制的模拟数据:", string(simulation))
}
func simulateModeExample() {
// 设置Hoverfly为模拟模式
resp, err := http.Get("http://localhost:8888/api/v2/hoverfly/mode?mode=simulate")
if err != nil {
fmt.Println("设置模拟模式失败:", err)
return
}
defer resp.Body.Close()
fmt.Println("Hoverfly已设置为模拟模式")
// 通过Hoverfly代理发送请求
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL("http://localhost:8500"),
},
}
// 发送请求到模拟API
resp, err = client.Get("https://jsonplaceholder.typicode.com/posts/1")
if err != nil {
fmt.Println("请求失败:", err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("模拟模式响应:", string(body))
}
使用说明
-
安装Hoverfly: 首先需要下载并安装Hoverfly,可以从官方GitHub仓库获取最新版本。
-
录制API流量:
- 将Hoverfly设置为录制模式
- 配置应用程序使用Hoverfly作为代理
- 所有经过Hoverfly的请求将被记录
-
模拟API响应:
- 将Hoverfly设置为模拟模式
- 导入之前录制的API流量或手动创建模拟
- 应用程序可以继续运行而不需要访问真实API
-
高级功能:
- 添加延迟模拟网络条件
- 创建故障场景测试应用程序的恢复能力
- 使用中间件动态修改请求/响应
构建与测试
要在本地开发环境中设置Hoverfly:
- 安装Go语言环境
- 克隆Hoverfly仓库:
git clone https://github.com/SpectoLabs/hoverfly.git
- 构建项目:
cd hoverfly make build
- 运行测试:
make test
许可证
Hoverfly使用Apache License version 2.0许可证。
更多关于golang HTTP(S)代理录制与模拟REST/SOAP API插件库hoverfly的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang HTTP(S)代理录制与模拟REST/SOAP API插件库hoverfly的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Hoverfly进行Golang HTTP(S)代理录制与API模拟
Hoverfly是一个轻量级的服务虚拟化工具,可以用于录制和模拟HTTP(S)流量,特别适合REST/SOAP API的测试场景。下面我将介绍如何在Golang中使用Hoverfly。
Hoverfly核心功能
- 流量录制:捕获真实API请求和响应
- 流量模拟:根据录制的数据模拟API行为
- 中间人代理:支持HTTPS流量拦截
- 行为定制:可以修改响应延迟、错误率等
安装Hoverfly
首先需要下载Hoverfly二进制文件:
# Linux/macOS
curl -L https://github.com/SpectoLabs/hoverfly/releases/download/v1.6.0/hoverfly_bundle_OSX.zip -o hoverfly.zip
unzip hoverfly.zip
chmod +x hoverfly
# Windows
# 下载 https://github.com/SpectoLabs/hoverfly/releases
Golang中使用Hoverfly
1. 启动Hoverfly作为代理
package main
import (
"fmt"
"os/exec"
"time"
)
func startHoverfly(adminPort, proxyPort int) (*exec.Cmd, error) {
cmd := exec.Command(
"./hoverfly",
"-pp", fmt.Sprintf("%d", proxyPort), // 代理端口
"-ap", fmt.Sprintf("%d", adminPort), // 管理端口
"-db", "memory",
)
err := cmd.Start()
if err != nil {
return nil, err
}
// 等待Hoverfly启动
time.Sleep(2 * time.Second)
return cmd, nil
}
func main() {
hoverfly, err := startHoverfly(8888, 8500)
if err != nil {
panic(err)
}
defer hoverfly.Process.Kill()
fmt.Println("Hoverfly started on port 8500")
// 在这里进行你的测试...
}
2. 录制API流量
import (
"net/http"
"net/url"
)
func recordMode(adminPort int) error {
adminURL := fmt.Sprintf("http://localhost:%d/api/v2/hoverfly/mode", adminPort)
req, err := http.NewRequest("PUT", adminURL, bytes.NewBufferString(`{"mode":"capture"}`))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("failed to set capture mode")
}
return nil
}
3. 使用代理发送请求
func makeRequestThroughProxy(targetURL string, proxyPort int) (string, error) {
proxyURL, _ := url.Parse(fmt.Sprintf("http://localhost:%d", proxyPort))
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
},
}
resp, err := client.Get(targetURL)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}
4. 切换到模拟模式并使用录制的数据
func simulateMode(adminPort int) error {
adminURL := fmt.Sprintf("http://localhost:%d/api/v2/hoverfly/mode", adminPort)
req, err := http.NewRequest("PUT", adminURL, bytes.NewBufferString(`{"mode":"simulate"}`))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("failed to set simulate mode")
}
return nil
}
5. 导出和导入模拟数据
func exportSimulationData(adminPort int, filePath string) error {
exportURL := fmt.Sprintf("http://localhost:%d/api/v2/simulation", adminPort)
resp, err := http.Get(exportURL)
if err != nil {
return err
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
return os.WriteFile(filePath, data, 0644)
}
func importSimulationData(adminPort int, filePath string) error {
data, err := os.ReadFile(filePath)
if err != nil {
return err
}
importURL := fmt.Sprintf("http://localhost:%d/api/v2/simulation", adminPort)
req, err := http.NewRequest("PUT", importURL, bytes.NewBuffer(data))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("failed to import simulation data")
}
return nil
}
完整示例工作流
func main() {
// 1. 启动Hoverfly
hoverfly, err := startHoverfly(8888, 8500)
if err != nil {
panic(err)
}
defer hoverfly.Process.Kill()
// 2. 设置为录制模式
err = recordMode(8888)
if err != nil {
panic(err)
}
// 3. 通过代理发送请求(会被录制)
response, err := makeRequestThroughProxy("https://api.example.com/data", 8500)
if err != nil {
panic(err)
}
fmt.Println("Recorded response:", response)
// 4. 导出录制的数据
err = exportSimulationData(8888, "simulation.json")
if err != nil {
panic(err)
}
// 5. 切换到模拟模式
err = simulateMode(8888)
if err != nil {
panic(err)
}
// 6. 现在请求会返回录制的响应
simulatedResponse, err := makeRequestThroughProxy("https://api.example.com/data", 8500)
if err != nil {
panic(err)
}
fmt.Println("Simulated response:", simulatedResponse)
}
高级功能
- 延迟模拟:可以配置响应延迟
- 故障注入:模拟错误响应
- 请求修改:修改请求/响应头或体
- 条件匹配:基于请求头、体等条件返回不同响应
Hoverfly提供了强大的API测试能力,特别适合以下场景:
- 开发时模拟依赖服务
- 自动化测试中的服务虚拟化
- 性能测试中的服务隔离
- API行为研究和分析
通过Golang与Hoverfly的结合,你可以构建强大的API测试和模拟框架。