【问题标题】:Randomly failing Specflow testsSpecflow 测试随机失败
【发布时间】:2013-03-19 21:53:42
【问题描述】:

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

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

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

  • 在每个场景之前,都会启动一个新的 IIS 进程和一个新的 BrowserSession;
  • 场景已运行;
  • 在每个场景之后,IIS 进程和 BrowserSession 都会终止;

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

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

提前谢谢你!

【问题讨论】:

  • 静态类是一种可能。但是没有代码,这个问题是无法回答的。请仔细查看失败的测试。你能看到一个模式吗?也许有些测试永远不会失败,而其他测试偶尔会失败?仔细看看那些失败的。
  • 您能再解释一下“静态类是一种可能性”吗?我仔细研究了失败的测试,但看不到模式。这里最奇怪的是,它们似乎只在测试集变大时才会失败。

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


【解决方案1】:

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

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

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

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


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

    例如,考虑这个类:

    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 而不是当前时间。这是一个测试如何影响不同测试的一个例子。

    【讨论】:

      猜你喜欢
      • 2020-03-13
      • 2016-01-31
      • 2021-06-03
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      • 2015-03-15
      • 1970-01-01
      相关资源
      最近更新 更多