为什么我的测试一起运行时失败,但单独运行时却通过?

问题描述 投票:0回答:9

当我在 Visual Studio 中编写测试时,我通过保存、构建然后在 Nunit 中运行测试来检查它是否有效(右键单击测试然后运行)。

测试有效,是的... 所以我继续...

现在我编写了另一个测试,它可以正常工作,就像我像上面一样保存并测试它一样。但是,当它们一起运行时,它们不起作用。

这是我的两个测试,它们在单独运行时有效,但在一起运行时失败:

using System;
using NUnit.Framework;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium;

namespace Fixtures.Users.Page1
{
    [TestFixture]
    public class AdminNavigateToPage1 : SeleniumTestBase
    {
        [Test]
        public void AdminNavigateToPage1()
        {
            NavigateTo<LogonPage>().LogonAsCustomerAdministrator();
            NavigateTo<Page1>();
            var headerelement = Driver.FindElement(By.ClassName("header"));

            Assert.That(headerelement.Text, Is.EqualTo("Page Title"));
            Assert.That(Driver.Url, Is.EqualTo("http://localhost/Page Title"));
        }

        [Test]
        public void AdminNavigateToPage1ViaMenu()
        {
            NavigateTo<LogonPage>().LogonAsCustomerAdministrator();
            Driver.FindElement(By.Id("menuitem1")).Click();
            Driver.FindElement(By.Id("submenuitem4")).Click();
            var headerelement = Driver.FindElement(By.ClassName("header"));

            Assert.That(headerelement.Text, Is.EqualTo("Page Title"));
            Assert.That(Driver.Url, Is.EqualTo("http://localhost/Page Title"));
        }
    }
}

当第二次测试因一起运行而失败时

Nunit 介绍了这个:

Sse.Bec.Web.Tests.Fixtures.ManageSitesAndUsers.ChangeOfPremises.AdminNavigateToChangeOfPremises.AdminNavigateToPageChangeOfPremisesViaMenu: OpenQA.Selenium.NoSuchElementException:找不到元素

此行突出显示:

var headerelement = Driver.FindElement(By.ClassName("header"));

有谁知道为什么我的代码一起运行时会失败,但单独运行时会通过?

任何答案将不胜感激!

c# visual-studio-2010 selenium-ide nunit-2.5
9个回答
17
投票

当单元测试以某种方式使用共享资源/数据时,通常会发生这种情况。

  1. 如果您的被测系统具有静态字段/属性,这些静态字段/属性被用来计算您断言的输出,也可能会发生这种情况。
  2. 如果被测系统正在共享(静态)依赖项,则可能会发生这种情况。

3
投票

有两件事你可以尝试

  1. 将断点放在以下两行之间。当第二行被点击时看看你在哪个页面

  2. 通过 Thread.Sleep 在这两行之间引入轻微的延迟

    Driver.FindElement(By.Id("submenuitem4")).Click();
    var headerelement = Driver.FindElement(By.ClassName("header"));
    

3
投票

如果上面的答案都不适合您,我通过在失败的测试中的断言之前添加

Thread.Sleep(1)
解决了这个问题...

看起来测试同步在某处丢失...请注意,我的测试不依赖于顺序,我没有任何静态成员或外部依赖项。


2
投票

查看 TestFixtureSetupSetupTestFixtureTearDownTearDown
这些属性允许您设置一次测试环境,而不是每次测试一次。


2
投票

在不知道 Selenium 如何工作的情况下,我的赌注是

Driver
,它似乎是一个静态类,因此两个测试共享状态。共享状态的一个例子是
Driver.Url
。因为测试是并行运行的,所以存在一个竞争条件来设置该对象的状态。

也就是说,我没有适合你的解决方案:)


0
投票

您确定在运行其中一项测试后该方法

NavigateTo<LogonPage>().LogonAsCustomerAdministrator();

会带你回到你应该去的地方吗?失败似乎是由于导航处理程序不正确造成的(假设标头元素存在并在两个测试中都找到)。


0
投票

我认为您需要确保您可以登录进行第二次测试,这可能会失败,因为您已经登录了?

-> 将登录放入 设置方法 或(因为看起来您在两个测试中使用同一用户)甚至直到 夹具设置 -> 注销(如果需要)可以放在拆卸方法中

     [SetUp]
     public void LaunchTest()
     {
        NavigateTo<LogonPage>().LogonAsCustomerAdministrator();
     }

     [TearDown]
     public void StopTest()
     {
        // logoff
     }
     [Test]
     public void Test1()
     {...}
     [Test]
     public void Test2()
     {...}

如果 DOM 中有延迟而不是 thread.sleep,我建议结合使用 webdriver.wait 和条件。睡眠可能对 80% 的人有效,而对其他人则无效。等待轮询直到达到超时,这更可靠且可读。这是我通常如何处理这个问题的例子:

    var webDriverWait = new WebDriverWait(webDriver, ..);
    webDriverWait.Until(d => d.FindElement(By.CssSelector(".."))
        .Displayed))

0
投票

我意识到这是一个非常古老的问题,但我今天才遇到它,没有一个答案能解决我的具体情况。

使用 Selenium 和 NUnit 进行前端自动化测试。

就我而言,我在启动时使用了

[OneTimeSetUp]
[OneTimeTearDown]
试图提高效率。

然而,这存在使用共享资源的问题,在我的例子中是驱动程序本身和我用来验证/获取元素的帮助程序。

也许是一个奇怪的边缘情况 - 但我花了几个小时才弄清楚。


0
投票

我在 C++ 中也遇到了类似的问题。 事实证明我使用了未初始化的变量值,这导致了 未定义的行为,根据未保留内存的内容而变化。

我怀疑存在某种内存问题,并决定使用 valgrind 运行单元测试。

Valgrind 给出了以下形式的错误:

==1795== 条件跳转或移动取决于未初始化的值

事实上,我的代码使用了未初始化的值,这当然会导致不确定的行为,具体取决于运行代码时该内存位置中发生的垃圾。

我遇到的错误类型是这样的:

    class MyClass
    {
        public:
        MyClass();
        void InitStuff(const bool flagIn)
        
        private:
        bool flag;
    };
    
    void MyClass::InitStuff(const bool flagIn)
    {
        if (flag) // Bug! I'm using member variable flag, not flagIn
        {
            DoStuff();
        }
        flag = flagIn;
    }

因此,我建议检查您的代码是否使用了未初始化值。

© www.soinside.com 2019 - 2024. All rights reserved.