# 集成测试 ## 概述 这个目录包含了 nnet 网络库的集成测试。集成测试验证服务器和客户端之间的实际网络通信。 ## 测试框架 集成测试框架提供了以下辅助函数: - `StartTestServer()` - 启动测试服务器(使用随机端口) - `NewTestClient()` - 创建测试客户端 - `ConnectTestClient()` - 连接测试客户端 - `RequestWithTimeout()` - 发送请求并等待响应 - `CleanupTestServer()` - 清理测试服务器 - `CleanupTestClient()` - 清理测试客户端 ## 运行测试 ### 运行所有集成测试 ```bash go test ./test/integration -v ``` ### 运行特定测试 ```bash go test ./test/integration -v -run TestBasicServerClient ``` ### 运行测试并显示覆盖率 ```bash go test ./test/integration -v -cover ``` ## 测试用例 ### 基础测试 (basic_test.go) - `TestBasicServerClient` - 测试基本服务器-客户端通信 - `TestEchoRoute` - 测试 Echo 路由 - `TestMultipleClients` - 测试多个客户端连接 ### 路由测试 (router_test.go) - `TestRouterFrameData` - 测试帧数据路由 - `TestRouterMiddleware` - 测试路由中间件 ### 协议测试 (protocol_test.go) - `TestProtocolVersion` - 测试协议版本管理 ### 拦截器测试 (interceptor_test.go) - `TestInterceptorValidation` - 测试拦截器验证 ### 编解码器测试 (codec_test.go) - `TestCodecJSON` - 测试JSON编解码器 - `TestCodecBinary` - 测试二进制编解码器 - `TestRouteNotFound` - 测试路由未找到场景 ## 注意事项 1. **端口冲突**:测试使用随机端口,避免端口冲突 2. **超时设置**:测试设置了合理的超时时间(5秒) 3. **资源清理**:所有测试都会自动清理资源(服务器、客户端) 4. **并发安全**:测试框架是并发安全的,可以并行运行测试 5. **Windows防火墙**:在Windows上运行时,可能需要点击防火墙确认对话框 6. **服务器启动**:测试会等待服务器真正启动并准备好接收连接 7. **路由注册**:路由必须在服务器启动前注册 8. **数据格式**:客户端发送的数据会自动添加换行符(服务器会自动去掉) ## 与示例代码的关系 集成测试基于 `examples/` 目录中的示例代码,但进行了以下改进: 1. **自动化**:无需手动启动服务器和客户端 2. **断言验证**:使用 `testify` 进行断言验证 3. **资源管理**:自动清理资源,避免资源泄漏 4. **随机端口**:使用随机端口,避免端口冲突 5. **错误处理**:完善的错误处理和超时机制 ## 扩展测试 要添加新的集成测试: 1. 在 `test/integration/` 目录创建新的测试文件 2. 使用测试框架提供的辅助函数 3. 遵循现有的测试模式 4. 确保测试可以独立运行 示例: ```go func TestMyFeature(t *testing.T) { cfg := &nnet.Config{ Addr: "tcp://:0", } ts := StartTestServer(t, cfg) defer CleanupTestServer(t, ts) // 注册路由 ts.Server.Router().RegisterString("test", func(ctx nnet.Context) error { return ctx.Response().WriteString("OK\n") }) // 创建客户端 client := NewTestClient(t, ts.Addr, nil) defer CleanupTestClient(t, client) // 连接客户端 ConnectTestClient(t, client) // 发送请求 resp := RequestWithTimeout(t, client, []byte("test"), 2*time.Second) assert.Contains(t, string(resp), "OK") } ```