You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Reqnroll自定义Retry Hook的ScenarioExecutionRetry方法?

Reqnroll(新版Specflow)自定义重试Hook:实现ScenarioExecutionRetry方法

我正在为Reqnroll(新版Specflow)构建自定义Retry Hook,想要实现失败测试最多重试n次的逻辑,但在重新执行失败测试时遇到困难。以下是目前编写的代码,请问如何编写ScenarioExecutionRetry方法?

namespace Hooks.SharedHooks
{
    [Binding]
    public class RetryHook
    {
        private int _retryCount;
        private const int DefaultMaxRetries = 2;
        private static readonly Regex RetryTag = new Regex(@"^Retry");
        private static readonly Regex RetryTagNumberRegex = new Regex(@"^Retry\(\d+\)$"); // 修正原正则语法错误

        [BeforeScenario("Retry","Retry*")]
        public void BeforeScenario()
        {
            _retryCount = 0;
        }

        [AfterScenario("Retry", "Retry*", Order = 0)]
        public void AfterScenario(ScenarioContext scenarioContext, ITestRunnerManager testRunnerManager)
        {
            var maxRetries = GetMaxRetriesFromScenario(scenarioContext) ?? DefaultMaxRetries;
            while (_retryCount < maxRetries && scenarioContext.TestError != null)
            {
                _retryCount++;
                Console.WriteLine($"Attempting scenario '{scenarioContext.ScenarioInfo.Title}' try {_retryCount} of {maxRetries}");
                ScenarioExecutionRetry(scenarioContext, testRunnerManager); // 修正原方法名笔误
            } 
        }

        private int? GetMaxRetriesFromScenario(ScenarioContext scenarioContext)
        {
            foreach (var tag in scenarioContext.ScenarioInfo.Tags)
            {
                var match = RetryTagNumberRegex.Match(tag);
                if (match.Success && int.TryParse(match.Groups[1].Value, out int retries))
                {
                    return retries;
                }
            }
            return null;
        }

        private void ScenarioExecutionRetry(ScenarioContext scenarioContext,ITestRunnerManager manager)
        {
            // Logic to re-run the failed scenario
        }
    }
}

实现方案

1. 核心逻辑实现

要重新执行失败场景,需借助ITestRunnerManager获取测试运行器,重置场景上下文的错误状态后重新执行步骤。以下是ScenarioExecutionRetry的完整实现:

private void ScenarioExecutionRetry(ScenarioContext scenarioContext, ITestRunnerManager testRunnerManager)
{
    // 获取当前场景对应的测试运行器
    var testRunner = testRunnerManager.GetTestRunner(scenarioContext.ScenarioInfo);

    // 重置场景上下文的错误标记,确保循环判断逻辑正常
    scenarioContext.SetTestError(null);

    try
    {
        // 重新执行当前场景的所有步骤
        testRunner.RunScenario(scenarioContext.ScenarioInfo);
    }
    catch (Exception ex)
    {
        // 重试失败时,将错误重新绑定到场景上下文,供下一次循环判断
        scenarioContext.SetTestError(ex);
        Console.WriteLine($"Retry {_retryCount} failed for scenario '{scenarioContext.ScenarioInfo.Title}': {ex.Message}");
    }
}

2. 异步优化(推荐)

Reqnroll框架更推荐异步执行模式,可将方法改为异步版本,避免阻塞测试进程:

// 修改AfterScenario为异步方法
[AfterScenario("Retry", "Retry*", Order = 0)]
public async Task AfterScenarioAsync(ScenarioContext scenarioContext, ITestRunnerManager testRunnerManager)
{
    var maxRetries = GetMaxRetriesFromScenario(scenarioContext) ?? DefaultMaxRetries;
    while (_retryCount < maxRetries && scenarioContext.TestError != null)
    {
        _retryCount++;
        Console.WriteLine($"Attempting scenario '{scenarioContext.ScenarioInfo.Title}' try {_retryCount} of {maxRetries}");
        await ScenarioExecutionRetryAsync(scenarioContext, testRunnerManager);
    } 
}

// 异步版本的重试执行方法
private async Task ScenarioExecutionRetryAsync(ScenarioContext scenarioContext, ITestRunnerManager testRunnerManager)
{
    var testRunner = testRunnerManager.GetTestRunner(scenarioContext.ScenarioInfo);
    scenarioContext.SetTestError(null);

    try
    {
        await testRunner.RunScenarioAsync(scenarioContext.ScenarioInfo);
    }
    catch (Exception ex)
    {
        scenarioContext.SetTestError(ex);
        Console.WriteLine($"Retry {_retryCount} failed for scenario '{scenarioContext.ScenarioInfo.Title}': {ex.Message}");
    }
}

3. 使用说明

  • 给需要重试的场景添加@Retry标签:将使用默认的2次重试
  • 添加@Retry(3)标签:将使用指定的3次重试

内容的提问来源于stack exchange,提问作者rtgher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:27:28