【问题标题】:Parallel Testing with MBUnit/Gallio using Data Driven Test Cases使用数据驱动的测试用例使用 MBUnit/Gallio 进行并行测试
【发布时间】:2012-01-19 11:58:01
【问题描述】:

我一直在阅读 RemoteWebDriver 上使用 Selenium Grid 的 Selenium 2。目前我的测试是使用[Test] 属性在Test() 中生成的。

我有一个 TestCriteria 类,我用它填充信息,然后使用 Selenium WebDriver“页面对象设计模式”作为“控制”如何将这些数据输入到我的测试中的一种方式。

所以,我有一个简单的条件对象,例如:

public class Credentials
{ 
    public string Username { get; set; } 
    public string Password { get; set; }
}

然后在 LoginPage 对象中使用此信息。

public class LoginPage
{
    [FindsByAnnotation]
    public IWebElement UsernameField { get; set; }

    [FindsByAnnotation]
    public IWebelement PasswordField { get; set; }

    [FindsByAnnotation]
    public IWebelement SubmitButton { get; set; }

    public HomePage Login(Credentials cred)
    {
         UsernameField.SendKeys(cred.user);
         // code for login and return new HomePage object
    }
}

现在,有了这种结构,一旦我有了测试数据,我就可以在我的测试中创建一些好的方法链接,比如我的 Credentials 对象、需要在其他页面上填写的数据等。

[TestFixture]
public class TestFixture
{
     private IWebDriver driver;
     private TestCaseData data; // Which contains a Credentials object etc etc

     [SetUp]
     public void SetUp()
     {
         data = new TestCaseData() 
         { 
              Credentials = new Credentials() 
              { 
                   Username = "username", 
                   Password = "password"
              }
             // Other test case data objects can be populated here 
         };

         driver = new FireFoxDriver();
     }

     [Test]
     public void Test()
     {
          new LoginPage().Login(data.Credentials)
                         .NavigateToSearchPage()
                         .EnterSearchCriteria(data.SearchCritiera)
          // etc
     }

}

这一切都很好,但是......如果我想从可以从 XML 反序列化的序列化 TestData 对象中加载这个测试数据。

我也有兴趣使用 RemoteWebDriver,我已经使用过,但与仅使用 IWebDriver driver = new FireFoxDriver(); 相比仍然很脆弱,但是忽略这些问题,我真的很想多次运行 TESTCASE...同时。这让我想到了并行测试的问题。

我知道 MBUnit 可以处理这个问题,它是 Gallio 的一部分,我也研究过 PUnit,它是 Nunit 的扩展,但它还有很长的路要走。所以我决定坚持使用 MbUnit。

这使我能够使用属性[Parallelizable] 运行TestFixtures。因此,如果我编译我的项目并将项目 dll 加载到 Gallio TestRunner GUI 中,我可以同时运行 4 个测试用例,这反过来又会打开 4 个浏览器同时运行每个测试,也可以给网站施加压力当所有 4 个测试都在运行时。 (显然,这将增加为在多台机器上使用 selenium RemoteWebDriver 和 Selenium Grid 运行数百个浏览器。

这里有没有人知道我可以加载一组 xml 序列化对象的方法,生成新的 TestFixture 对象,这些对象可以将 [Parallelizable] 属性添加到测试夹具的顶部并让它们同时运行在从 a 加载 1 - 10 个 .xml 文件后,例如:C:\TestCase 目录?

我的想法是加载所有这些,然后让 Selenium Grid 处理浏览器会话,其中 1 - 5 个 Selenium 节点运行连接到主 selenium 网格集线器。

当我找不到允许我生成 Test Fixture 的框架时,我很难真正利用 Selenium Grid,其中包括 [SetUp] [TearDown] [Test] 和设置某些测试属性的测试条件取决于从 TestCase .xml 文件加载的内容。

例如,如果一个 TestCase .xml 文件有一个失败的元素,那么我如何加载这个 .xml 文件并为此在我的 TestFixture 的 [Test] 上设置一个属性,或者将 TestCase .xml 描述映射到运行时的[Test(Description = "")] 属性。

我已经知道 selenium webdriver 的功能、页面对象设计模式、用于屏幕截图的 selenium EventFiringWebDriver 功能。

如何利用加载几个 XML 序列化的 TestCaseData 的能力,在这些加载后生成新的 TestFixture 对象?

理想情况下,我希望每个 TestFixture 的 [SetUp] 设置 IWebDriver,因为某些 URL 会根据 TestCase.xml 文件包含的内容而有所不同,例如,此测试是在 UAT 环境中运行,测试环境,Pre-Production 环境,我需要在测试运行前设置好这个。

有没有人有一个基本示例,它将这些主要概念与 Selenium Grid/Selenium WebDriver 一起使用,并能够并行运行这些测试装置以利用运行多个浏览器的 Selenium Grid 功能。

所以我在伪代码中寻找一些东西。

public class Main()
{
   // Load Testfixtures
   List<TestCase> testCases = Deserialise("\\Some\\FolderLocation");

   foreach(test in testCases)
   { 
      // create NEW testFixture, not [Test]
      // ability to attach parallel TestFixture
   }  
}

[Testfixture]
[Parallelizable]
public class TestFixture
{

     public TestCase testCase { get; set; }
     public IWebDriver driver { get; set; }

     [SetUp]
     public void SetUp()
     {
         if(testCase.Environment == "UAT")
         {
             driver = new FireFoxDrive()
             driver.NavigateTo("http://localhost/uat/Login");
         }

         // What if the testCase.ShouldPass is false?

         // How can i generate my [Test] with ExpectedException?

     }

      [Test]
      public void Test()
      {
          // code here with page object method chaining passing in testCase data objects  
      }
}

也许我以错误的方式进行此设计。请就并行化这些的最佳方式提出任何建议?

【问题讨论】:

    标签: selenium webdriver mbunit selenium-grid parallel-testing


    【解决方案1】:

    这个怎么样?

    public class TestCase
    {
        public string Name { get; set; }
    }
    
    public static class TestCaseFactory
    {
        public static IEnumerable<TestCase> TestCases()
        {
            yield return new TestCase { Name = "one" };
            yield return new TestCase { Name = "two" };
        }
    }
    
    [Factory(typeof(TestCaseFactory), "TestCases"), Parallelizable]
    public class DataDrivenFixture
    {
        private readonly TestCase testCase;
    
        public DataDrivenFixture(TestCase testCase)
        {
            this.testCase = testCase;
        }
    
        [SetUp]
        public void SetUp()
        {
            Console.WriteLine("SetUp " + testCase.Name);
        }
    
        [Test]
        public void Test()
        {
            Console.WriteLine("Test " + testCase.Name);
        }
    }
    

    【讨论】:

    • 我最终发现了这个,太棒了,我发现与 Nunit TestCaseSource 几乎相同。谢谢:) +1
    【解决方案2】:

    很好的解决方案。 但是在并行的不同浏览器中运行测试呢? 如果我在 [FixtureSetUp] 中初始化 IWebDriver,则浏览器打开并运行测试但出现错误(基本上是 NoSuchElement)。

    public static IEnumerable<TestCase> TestCases()
            {
                yield return new TestCase { Name = "internet explorer" };
                yield return new TestCase { Name = "firefox" };
            }
    
    [FixtureSetUp]
            public void SetUp()
            {
                Console.WriteLine("SetUp " + testCase.Name);
                switch (testCase.Name)
                {
                    case "internet explorer":
                        driver = new InternetExplorerDriver();
                        break;
                    case "chrome":
                        driver = new ChromeDriver();
                        break;
                    case "firefox":
                        driver = new FirefoxDriver();
                        break;
                }
            }
    

    【讨论】:

    • 如果要并行运行测试,则必须充分利用 selenium GRID。这样,selenium 网格可以跟踪会话以及它应该向哪些浏览器发送请求。
    • 我尝试在没有它的情况下在 Grid 上运行。没关系,测试失败,没有这样的元素。我认为因为 Webdriver 不是线程安全的。但我不知道如何使 WebDriver 安全线程或其他方式同时与不同的浏览器一起使用。
    • 重点是使用 RemoteWebDriver,它不需要是线程安全的,因为您没有两次运行相同的 RemoteWebDriver,您创建了两个连接到 SAME Selenium Grid 2 服务器的 RemoteWebDriver 实例。这将为您处理浏览器。如果您向我展示了更多代码,则可能更容易理解您遇到的问题。您是否考虑过使用 TPL?这为您提供了并行执行任务的方法。您可以使用它作为在同一个 [Test] 中创建两个 RemoteWebDriver 实例的方法。 msdn.microsoft.com/en-us/library/dd537609.aspx
    • 看看nuget.org/packages/Saucery2nuget.org/packages/Saucery3。这些适用于 NUnit2 和 NUnit3。 Gallio MbUnit 似乎仍然存在此问题(v3.4.14)。 NUnit 3.2 将在 testfixture 中进行并行测试。 Beta 版已经支持跨测试装置的并行测试
    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多