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

SpecFlow C#:无法向ExtentReport输出Info级日志求助

解决ExtentReport中无法写入Status.Info日志的问题

1. 修复AfterStep钩子中的重复节点创建问题

你当前代码里的When分支两次调用CreateNode<When>,会生成两个独立的步骤节点,导致日志被附加到未关联当前步骤的节点上,因此无法正常显示。需要将节点保存到变量后再执行日志操作:

[AfterStep]
public void AfterStep(ScenarioContext scenarioContext)
{
    var scenario = scenarioContext["extentTest"] as ExtentTest;
    ScenarioBlock scenarioBlock = _scenarioContext.CurrentScenarioBlock;
    var exception = _scenarioContext.TestError;
    var mediaEntity = _driverHelper.CaptureScreenshot(_scenarioContext.ScenarioInfo.Title.Trim());

    if (exception == null)
    {
        ExtentTest stepNode = null;
        switch (scenarioBlock)
        {
            case ScenarioBlock.Given:
                stepNode = scenario?.CreateNode<Given>(_scenarioContext.StepContext.StepInfo.Text);
                break;
            case ScenarioBlock.When:
                stepNode = scenario?.CreateNode<When>(_scenarioContext.StepContext.StepInfo.Text);
                // 直接在当前步骤节点上添加日志
                stepNode?.Log(Status.Info, "Testing extent logs 2");
                break;
            case ScenarioBlock.Then:
                stepNode = scenario?.CreateNode<Then>(_scenarioContext.StepContext.StepInfo.Text);
                break;
            default:
                stepNode = scenario?.CreateNode<And>(_scenarioContext.StepContext.StepInfo.Text);
                break;
        }

        // 可选:添加表格数据到当前步骤
        if (costToUseData != null && stepNode != null)
        {
            var costTable = MarkupHelper.CreateTable(costToUseData);
            stepNode.Log(Status.Info, costTable);
        }

        // 可选:添加步骤截图
        stepNode?.Log(Status.Info, "步骤截图", mediaEntity);
    }
    else
    {
        // 异常处理逻辑保持不变,确保错误日志附加到当前步骤节点
        switch (scenarioBlock)
        {
            case ScenarioBlock.Given:
                scenario?.CreateNode<Given>(_scenarioContext.StepContext.StepInfo.Text)
                    .Fail(_scenarioContext.TestError.Message, mediaEntity);
                break;
            case ScenarioBlock.When:
                scenario?.CreateNode<When>(_scenarioContext.StepContext.StepInfo.Text)
                    .Fail(_scenarioContext.TestError.Message, mediaEntity);
                break;
            case ScenarioBlock.Then:
                scenario?.CreateNode<Then>(_scenarioContext.StepContext.StepInfo.Text)
                    .Fail(_scenarioContext.TestError.Message, mediaEntity);
                break;
            default:
                scenario?.CreateNode<And>(_scenarioContext.StepContext.StepInfo.Text)
                    .Fail(_scenarioContext.TestError.Message, mediaEntity);
                break;
        }
    }

    Logger.Log.Info(ScenarioContext.Current.ScenarioInfo.Title);
}

2. 从StepDefinition或页面逻辑写入Info日志

要在步骤定义或页面逻辑中直接写入ExtentReport日志,可通过ScenarioContext获取当前ExtentTest实例,或封装通用日志类统一处理:

方法一:在StepDefinition中直接调用日志

[Given("用户登录系统")]
public void GivenUserLogsIn()
{
    // 获取当前场景的ExtentTest实例
    var extentTest = ScenarioContext.Current["extentTest"] as ExtentTest;
    
    // 写入Info日志
    extentTest.Log(Status.Info, "开始执行登录操作");
    
    // 页面逻辑代码
    loginPage.EnterUsername("testuser");
    extentTest.Log(Status.Info, "已输入用户名");
    
    loginPage.EnterPassword("password");
    extentTest.Log(Status.Info, "已输入密码");
    
    loginPage.ClickLoginButton();
    extentTest.Log(Status.Info, "已点击登录按钮");
}

方法二:创建通用日志辅助类(适配页面逻辑)

封装静态类实现跨场景的日志调用:

public static class ExtentLogger
{
    public static void LogInfo(string message)
    {
        var extentTest = ScenarioContext.Current["extentTest"] as ExtentTest;
        extentTest?.Log(Status.Info, message);
    }

    public static void LogInfo(Markup markup)
    {
        var extentTest = ScenarioContext.Current["extentTest"] as ExtentTest;
        extentTest?.Log(Status.Info, markup);
    }
}

在页面逻辑中使用:

public class LoginPage
{
    public void EnterUsername(string username)
    {
        // 页面元素操作
        usernameInput.SendKeys(username);
        // 写入日志
        ExtentLogger.LogInfo($"已输入用户名:{username}");
    }
}

3. 确保ExtentTest实例正确初始化

需在BeforeScenario钩子中创建并存储ExtentTest实例到ScenarioContext,确保后续能正常获取:

[BeforeScenario]
public void BeforeScenario(ScenarioContext scenarioContext)
{
    var extentTest = extentReports.CreateTest(scenarioContext.ScenarioInfo.Title);
    scenarioContext["extentTest"] = extentTest;
}

完成以上修改后,无论是AfterStep钩子、StepDefinition还是页面逻辑中的Status.Info日志,都能正确写入ExtentReport。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:06:13