随机失败的Specflow测试

时间:2012-10-04 13:33:39

标签: c# visual-studio-2010 testing bdd specflow

前置主题:
虽然我在前面Specflow stability主题中提到了这个问题,但我想在一个新主题中重新提出这个问题。这是因为上一个主题的标题具有误导性(我现在认为Specflow稳定性不是问题),我可以更精确地解决问题。

问题:
当我运行50个左右的测试的完整测试集时,大多数时候随机地有一个或两个测试失败(有时没有测试失败)。当我将完整的测试集切割成较小的测试集(例如,为每个单独的用户故事测试7或8个测试集)时,这些集合单独运行,所有测试都通过。就像Luke McGregor在Specflow stability中所说的那样,似乎测试正在共享数据,因此失败了。但是为什么只有在运行完整集时才会发生这种情况,而不是在我使用较小的集时?

背景:
我正在尝试运行一组50左右的Specflow测试。所有这些测试都旨在测试网站的UI。测试在Visual Studio 2010中运行,使用MsTest作为跑步工具。使用的浏览器是FireFox。现在,测试中采取的步骤是:

  • 在每个方案之前,启动新的IIS进程和新的BrowserSession;
  • 运行场景;
  • 在每个方案之后,IIS Proccess和BrowserSession终止;

我在每个单独的测试场景之前启动新的IIS进程和新的BrowserSession的原因是为了最小化“数据共享”的风险,Luke提到。不幸的是无济于事。

我现在有点迷失了问题所在。我在这里错过了一些明显(或者可能不那么明显)的东西吗?

提前谢谢!

2 个答案:

答案 0 :(得分:3)

如果你能给出一些测试失败的例子,那将会有所帮助。

测试失败是因为他们在页面上找不到某些元素吗? 如果是这种情况,如果您使用的是WebDriver,我建议您启用implicits等待。 这将使您的测试套件运行速度变慢,但您将获得稳定性。

WebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));

通过浏览器进行测试会导致随机故障,特别是如果您的测试不是为了等待元素出现在页面上而设计的。使用ajax调用时,事情变得非常棘手。

另外请注意,我建议您在每次测试之前避免运行新浏览器并启动IIS。原因是您的测试套件需要很长时间才能运行。 相反,我建议: - 您在测试套件的开头只运行一次IIS。 (你可以使用标签[BeforeTestRun]) - 在测试套件开始时只打开一次浏览器会话。 ([BeforeTestRun]) - 在每次测试结束时,只需注销用户,以便清除所有cookie。 ([AfterScenario])

这将大大加快您的测试套件。

关于共享状态,我建议您使用属性[BeforeScenario]重置测试使用的所有数据。 因此,例如,如果您的测试在数据库中设置数据,您将在每次测试运行之前清理数据库。

最后,确保您的测试是自包含的:不应该使用其他测试使用的数据。测试需要始终从干净的初始状态运行并创建所需的数据。

答案 1 :(得分:1)

静态类是一种可能性 请仔细查看失败的测试。你能看到一个模式吗?也许有些测试从未失败,而其他测试偶尔会失败?仔细看看那些失败的人。


多单元测试中使用的静态类是数据共享或状态共享的经典案例。

例如,考虑这个类:

public static class TimeProvider
{
    static TimeProvider()
    {
        CurrentTimeProvider = () => DateTime.Now;
    }

    public static Func<DateTime> CurrentTimeProvider { get; set; }

    public static DateTime Now { get { return CurrentTimeProvider(); } }
}

现在,假设一个单元测试想要测试当前时间相关的东西:

public void AddItemSetsOrderDateAsCurrentTime()
{
    // Arrange
    var currentTime = new DateTime(2011, 1, 1, 12, 15);
    TimeProvider.CurrentTimeProvider = () => currentTime;

    // Act
    //...
}

使用TimeProvider.Now的所有以下单元测试将获得2011-01-01 12:15而不是当前时间。这是一个测试如何影响不同测试的一个例子。