diff --git a/src/X1.Presentation/Controllers/TestScenariosController.cs b/src/X1.Presentation/Controllers/TestScenariosController.cs new file mode 100644 index 0000000..0dc8e46 --- /dev/null +++ b/src/X1.Presentation/Controllers/TestScenariosController.cs @@ -0,0 +1,247 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using X1.Application.Features.TestScenarios.Queries.GetTestScenarios; +using X1.Application.Features.TestScenarios.Queries.GetTestScenarioById; +using X1.Application.Features.TestScenarios.Commands.CreateTestScenario; +using X1.Application.Features.TestScenarios.Commands.UpdateTestScenario; +using X1.Application.Features.TestScenarios.Commands.DeleteTestScenario; +using X1.Application.Features.ScenarioTestCases.Commands.CreateScenarioTestCase; +using X1.Application.Features.ScenarioTestCases.Queries.GetScenarioTestCases; +using X1.Presentation.Abstractions; +using X1.Domain.Common; +using MediatR; +using Microsoft.Extensions.Logging; + +namespace X1.Presentation.Controllers; + +/// +/// 测试场景控制器 +/// +[ApiController] +[Route("api/testscenarios")] +[Authorize] +public class TestScenariosController : ApiController +{ + private readonly ILogger _logger; + + /// + /// 初始化测试场景控制器 + /// + public TestScenariosController(IMediator mediator, ILogger logger) + : base(mediator) + { + _logger = logger; + } + + /// + /// 获取测试场景列表 + /// + /// 搜索关键词 + /// 场景类型 + /// 启用状态 + /// 页码 + /// 每页大小 + /// 测试场景列表 + [HttpGet] + public async Task> GetTestScenarios( + [FromQuery] string? searchTerm = null, + [FromQuery] string? type = null, + [FromQuery] bool? isEnabled = null, + [FromQuery] int pageNumber = 1, + [FromQuery] int pageSize = 10) + { + _logger.LogInformation("获取测试场景列表,搜索条件: {SearchTerm}, 类型: {Type}, 启用状态: {IsEnabled}, 页码: {PageNumber}, 每页大小: {PageSize}", + searchTerm, type, isEnabled, pageNumber, pageSize); + + var query = new GetTestScenariosQuery + { + SearchTerm = searchTerm, + Type = !string.IsNullOrEmpty(type) && Enum.TryParse(type, out var scenarioType) ? scenarioType : null, + IsEnabled = isEnabled, + PageNumber = pageNumber, + PageSize = pageSize + }; + + var result = await mediator.Send(query); + if (!result.IsSuccess) + { + _logger.LogWarning("获取测试场景列表失败: {ErrorMessages}", string.Join(", ", result.ErrorMessages ?? new List())); + return result; + } + + _logger.LogInformation("成功获取测试场景列表,总数: {TotalCount}", result.Data?.TotalCount); + return result; + } + + /// + /// 根据ID获取测试场景详情 + /// + /// 测试场景ID + /// 是否包含测试用例 + /// 测试场景详情 + [HttpGet("{id}")] + public async Task> GetTestScenarioById( + string id, + [FromQuery] bool includeTestCases = false) + { + _logger.LogInformation("获取测试场景详情,ID: {Id}, 包含测试用例: {IncludeTestCases}", id, includeTestCases); + + var query = new GetTestScenarioByIdQuery + { + TestScenarioId = id, + IncludeTestCases = includeTestCases + }; + var result = await mediator.Send(query); + if (!result.IsSuccess) + { + _logger.LogWarning("获取测试场景详情失败,ID: {Id}, 错误: {ErrorMessages}", + id, string.Join(", ", result.ErrorMessages ?? new List())); + return result; + } + + _logger.LogInformation("成功获取测试场景详情,ID: {Id}, 名称: {Name}", + id, result.Data?.TestScenario?.ScenarioName); + return result; + } + + /// + /// 创建测试场景 + /// + /// 创建测试场景命令 + /// 创建结果 + [HttpPost] + public async Task> CreateTestScenario([FromBody] CreateTestScenarioCommand command) + { + _logger.LogInformation("开始创建测试场景,场景名称: {ScenarioName}, 类型: {Type}", + command.ScenarioName, command.Type); + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("创建测试场景失败,场景名称: {ScenarioName}, 错误: {ErrorMessages}", + command.ScenarioName, string.Join(", ", result.ErrorMessages ?? new List())); + return result; + } + + _logger.LogInformation("成功创建测试场景,ID: {Id}, 名称: {ScenarioName}", + result.Data?.Id, result.Data?.ScenarioName); + return result; + } + + /// + /// 更新测试场景 + /// + /// 测试场景ID + /// 更新测试场景命令 + /// 更新结果 + [HttpPut("{id}")] + public async Task> UpdateTestScenario( + string id, + [FromBody] UpdateTestScenarioCommand command) + { + _logger.LogInformation("开始更新测试场景,场景ID: {Id}", id); + + // 确保命令中的ID与路由参数一致 + command.TestScenarioId = id; + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("更新测试场景失败,场景ID: {Id}, 错误: {ErrorMessages}", + id, string.Join(", ", result.ErrorMessages ?? new List())); + return result; + } + + _logger.LogInformation("成功更新测试场景,场景ID: {Id}", id); + return result; + } + + /// + /// 删除测试场景 + /// + /// 测试场景ID + /// 删除结果 + [HttpDelete("{id}")] + public async Task> DeleteTestScenario(string id) + { + _logger.LogInformation("开始删除测试场景,场景ID: {Id}", id); + + var command = new DeleteTestScenarioCommand { TestScenarioId = id }; + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("删除测试场景失败,场景ID: {Id}, 错误: {ErrorMessages}", + id, string.Join(", ", result.ErrorMessages ?? new List())); + return result; + } + + _logger.LogInformation("成功删除测试场景,场景ID: {Id}", id); + return result; + } + + /// + /// 获取场景测试用例列表 + /// + /// 场景ID + /// 是否只获取启用的测试用例 + /// 是否包含详细信息 + /// 场景测试用例列表 + [HttpGet("{scenarioId}/testcases")] + public async Task> GetScenarioTestCases( + string scenarioId, + [FromQuery] bool? isEnabled = null, + [FromQuery] bool includeDetails = false) + { + _logger.LogInformation("获取场景测试用例列表,场景ID: {ScenarioId}, 启用状态: {IsEnabled}, 包含详情: {IncludeDetails}", + scenarioId, isEnabled, includeDetails); + + var query = new GetScenarioTestCasesQuery + { + ScenarioId = scenarioId, + IsEnabled = isEnabled, + IncludeDetails = includeDetails + }; + + var result = await mediator.Send(query); + if (!result.IsSuccess) + { + _logger.LogWarning("获取场景测试用例列表失败,场景ID: {ScenarioId}, 错误: {ErrorMessages}", + scenarioId, string.Join(", ", result.ErrorMessages ?? new List())); + return result; + } + + _logger.LogInformation("成功获取场景测试用例列表,场景ID: {ScenarioId}, 测试用例数量: {Count}", + scenarioId, result.Data?.ScenarioTestCases?.Count ?? 0); + return result; + } + + /// + /// 创建场景测试用例 + /// + /// 场景ID + /// 创建场景测试用例命令 + /// 创建结果 + [HttpPost("{scenarioId}/testcases")] + public async Task> CreateScenarioTestCase( + string scenarioId, + [FromBody] CreateScenarioTestCaseCommand command) + { + _logger.LogInformation("开始创建场景测试用例,场景ID: {ScenarioId}, 测试用例数量: {TestCaseCount}", + scenarioId, command.TestCases?.Count ?? 0); + + // 确保命令中的场景ID与路由参数一致 + command.ScenarioId = scenarioId; + + var result = await mediator.Send(command); + if (!result.IsSuccess) + { + _logger.LogWarning("创建场景测试用例失败,场景ID: {ScenarioId}, 错误: {ErrorMessages}", + scenarioId, string.Join(", ", result.ErrorMessages ?? new List())); + return result; + } + + _logger.LogInformation("成功创建场景测试用例,场景ID: {ScenarioId}, 成功数量: {SuccessCount}, 失败数量: {FailureCount}", + scenarioId, result.Data?.SuccessCount ?? 0, result.Data?.FailureCount ?? 0); + return result; + } +} diff --git a/src/modify.md b/src/modify.md index 565ef4a..9dc8373 100644 --- a/src/modify.md +++ b/src/modify.md @@ -27,6 +27,16 @@ 5. **删除测试场景** (`DELETE /api/testscenarios/{id}`) - 删除指定的测试场景 +6. **获取场景测试用例列表** (`GET /api/testscenarios/{scenarioId}/testcases`) + - 获取指定场景下的测试用例列表 + - 支持启用状态过滤 + - 支持包含详细信息选项 + +7. **创建场景测试用例** (`POST /api/testscenarios/{scenarioId}/testcases`) + - 为指定场景添加测试用例 + - 支持批量创建多个测试用例 + - 包含执行顺序、循环次数、启用状态等配置 + #### 技术特点: - 继承自 `ApiController` 基类 - 使用 MediatR 进行命令查询分离 @@ -38,6 +48,8 @@ #### 使用的命名空间: - `X1.Application.Features.TestScenarios.Queries.*` - `X1.Application.Features.TestScenarios.Commands.*` +- `X1.Application.Features.ScenarioTestCases.Queries.*` +- `X1.Application.Features.ScenarioTestCases.Commands.*` - `X1.Presentation.Abstractions` - `X1.Domain.Common`