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

SpecFlow生成LivingDoc报告仅显示最后执行测试结果问题排查

SpecFlow LivingDoc报告仅显示最后一个Feature通过的排查方案

问题现象

项目中20个Feature测试用例均执行通过,但生成LivingDoc报告时,仅最后执行的Feature显示为通过状态,其余Feature均显示「Not executed(未执行)」。

项目结构

|-Project
  +----Feature
  |------Login.feature
  +----Steps
  |------Login.cs
  +----Drivers
  |------SetDriver.cs
  +----Hooks
  |------BrowserHook.cs
  +----Pages
  |------PageObjectManager.cs
  |------LoginPage.cs

现有代码配置

Driver配置

public class SetDrivers
{
    private Lazy<IWebDriver> _driver;

    public SetDrivers()
    {
        _driver = new Lazy<IWebDriver>(Setup);
    }

    public IWebDriver Current => _driver.Value;

    public IWebDriver Setup()
    {
        var chromeDriverServices = ChromeDriverService.CreateDefaultService();
        var browserOption = GetBrowserOptions("chrome");

        var driver = new ChromeDriver(chromeDriverServices, browserOption);

        driver.Manage().Window.Maximize();

        return driver;
    }

    private dynamic GetBrowserOptions(String browserName)
    {
        if (browserName.ToLower() == "chrome")
        {
            return new ChromeOptions();
        }
        else if (browserName.ToLower() == "firefox")
        {
            return new FirefoxOptions();
        }
        else
        {
            return new ChromeOptions();
        }
    }
}

Hooks配置

[Binding]
public sealed class BrowserHooks
{

    [BeforeTestRun]
    public static void BeforeTestRun(ObjectContainer objectContainer)
    {
        objectContainer.BaseContainer.Resolve<SetDrivers>();
    }

    [BeforeScenario ("Smoke")]
    public static void BeforeSenerio(SetDrivers drivers)
    {
        var pageObjects = new PageObjectManager(drivers.Current);
        pageObjects.loadUrl();
    }

    [AfterScenario]
    public void AfterScenario(SetDrivers drivers)
    {
        var pageObjects = new PageObjectManager(drivers.Current);
        pageObjects.tearDown();
    }
}

步骤定义

[Binding]
public class LoginSteps
{
    private LoginPage _loginPage;

    public LoginSteps(SetDrivers drivers)
    {
        _loginPage = new LoginPage(drivers.Current);
    }

    [Given(@"user is in login page")]
    public void GivenUserIsInLoginPage()
    {
        _loginPage.clickLoginBtn();
    }
    
    [When(@"user Enters ""(.*)"" and ""(.*)""")]
    public void WhenUserEntersAnd(string email, string password)
    {
        _loginPage.setUserEmail(email);
        _loginPage.setPassword(password);
    }
    
    [When(@"click Login Button")]
    public void WhenClickLoginButton()
    {
        _loginPage.clickLogin();
    }
    
    [Then(@"Home Page should be visible")]
    public void ThenHomePageShouldBeVisible()
    {
        Assert.IsTrue(_loginPage.isLoggedIn());
    }
}

Feature用例

Feature: Login
    User login test

@Smoke
Scenario Outline: User wants to login with valid email and password
    Given user is in login page
    When user Enters "<Email>" and "<Password>"
    And click Login Button
    Then Home Page should be visible
    Examples:
        | Email         | Password |
        | mail@mail.com | 121212A  |

页面对象管理器

public class PageObjectManager
    {
        private const string url = "https://www.pinterest.com/";

        private readonly IWebDriver _webDriver;

        public PageObjectManager(IWebDriver webDriver)
        {
            _webDriver = webDriver;
        }
        public void loadUrl()
        {
            _webDriver.Url = url;
        }

        public void tearDown()
        {
            if (_webDriver != null)
            {
                _webDriver.Quit();
            }
        }
}

异常截图

LivingDoc报告
测试执行结果

根因与修复方案

核心原因(直接导致报告显示异常)

报告生成逻辑配置错误:如果分批次执行Feature,每次执行都将测试结果输出到同一路径的文件,默认dotnet test会覆盖旧的结果文件,不会追加内容;若生成LivingDoc时未开启结果合并参数,最终只会读取到最后一次执行的结果记录,因此仅最后一个Feature显示通过,其余均显示未执行。

修复方式二选一:

  • 单次执行全量用例:执行测试时指定统一的结果输出文件,确保20个Feature在同一次测试运行中完成,命令参考:
    dotnet test --logger "trx;LogFileName=all_test_results.trx"
    
    执行完成后基于这个全量结果文件生成LivingDoc即可。
  • 分批执行后合并结果:如果必须分批次跑用例,生成LivingDoc时添加--merge参数,传入所有批次的结果文件做合并,再生成报告。

附带代码问题(会导致用例执行不稳定,间接影响结果采集)

  1. SetDrivers未正确注册到SpecFlow DI容器:现有BeforeTestRun逻辑仅解析了一次SetDrivers实例,未做单例注册,SpecFlow会在不同请求域生成新的SetDrivers实例,导致driver实例不唯一。
    修复:修改BeforeTestRun逻辑,注册SetDrivers为全局单例:
    [BeforeTestRun]
    public static void BeforeTestRun(ObjectContainer objectContainer)
    {
        var driver = new SetDrivers();
        objectContainer.BaseContainer.RegisterInstanceAs<SetDrivers>(driver);
    }
    
  2. Driver实例未做重置:现有AfterScenario逻辑执行Quit()后没有重置Lazy包装的driver实例,下一个Scenario执行时会复用已经退出的driver,触发执行错误。
    修复:给SetDrivers类增加驱动重置方法:
    public void ResetDriver()
    {
        if (_driver.IsValueCreated)
        {
            _driver.Value.Quit();
            _driver.Value.Dispose();
            _driver = new Lazy<IWebDriver>(Setup);
        }
    }
    
    替换原有tearDown逻辑,Scenario执行完成后调用该方法重置驱动。
  3. BeforeScenario加了Smoke标签过滤:现有初始化逻辑仅对打了@Smoke标签的Scenario生效,未加该标签的Scenario不会触发页面加载,直接执行失败。需要确认其余19个Feature的Scenario是否都添加了@Smoke标签,若没有则去掉标签过滤,或给对应Scenario补上标签。

内容的提问来源于stack exchange,提问作者Tariful Islam Abir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:09:19