一、微服务测试挑战
微服务架构的分布式特性给测试带来了新的挑战,需要多层次、多角度的测试策略。
二、单元测试最佳实践
单元测试验证单个组件的功能,使用Mock隔离外部依赖。
[TestClass]
public class ProductServiceTests
{
private Mock<IProductRepository> _mockRepo;
private ProductService _service;
[TestInitialize]
public void Setup()
{
_mockRepo = new Mock<IProductRepository>();
_service = new ProductService(_mockRepo.Object);
}
[TestMethod]
public async Task GetProduct_ReturnsProduct_WhenExists()
{
// Arrange
var expectedProduct = new Product { Id = 1, Name = "Test" };
_mockRepo.Setup(r => r.GetByIdAsync(1))
.ReturnsAsync(expectedProduct);
// Act
var result = await _service.GetProductAsync(1);
// Assert
Assert.AreEqual(expectedProduct.Id, result.Id);
_mockRepo.Verify(r => r.GetByIdAsync(1), Times.Once);
}
}
三、集成测试策略
集成测试验证多个组件之间的交互。
public class ProductControllerIntegrationTests
{
private HttpClient _client;
private TestServer _server;
[SetUp]
public void Setup()
{
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
.ConfigureTestServices(services => {
// 替换测试依赖
services.AddScoped<IDbContext, TestDbContext>();
}));
_client = _server.CreateClient();
}
[Test]
public async Task GetProducts_ReturnsOk()
{
var response = await _client.GetAsync("/api/products");
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
Assert.IsNotNull(content);
}
}
四、契约测试
契约测试验证服务之间的API契约一致性。
// 使用 PactNet 进行契约测试
public class ProductApiConsumerTests
{
[Test]
public void GetProduct_ShouldReturnProduct()
{
using var pact = new PactBuilder(new PactConfig())
.ServiceConsumer("Consumer")
.HasPactWith("ProductService");
pact.UponReceiving("a request for product")
.Given("product 1 exists")
.WithRequest(HttpMethod.Get, "/api/products/1")
.WillRespondWith(HttpStatusCode.OK,
headers: new Dictionary<string, string> {
{ "Content-Type", "application/json" }
},
body: new {
id = 1,
name = "Test Product"
});
pact.Verify(() => {
var client = new ProductApiClient("http://localhost:9292");
var product = client.GetProduct(1);
Assert.AreEqual(1, product.Id);
});
}
}
五、端到端测试
端到端测试验证完整的业务流程。
六、组件测试
组件测试验证单个服务的完整功能。
七、性能测试
使用k6等工具进行性能和压力测试。
// k6 性能测试脚本
import http from 'k6/http';
import { sleep, check } from 'k6';
export const options = {
vus: 100,
duration: '30s',
};
export default function () {
const res = http.get('https://api.example.com/products');
check(res, {
'status was 200': (r) => r.status == 200,
'response time < 200ms': (r) => r.timings.duration < 200,
});
sleep(1);
}
八、测试数据管理
管理测试数据确保测试的可重复性。
九、测试覆盖率
使用Coverlet等工具衡量测试覆盖率。
十、测试策略总结
根据测试金字塔合理分配测试资源,注重测试的有效性和效率。