Selenium Parallel testing with extension methods

天涯浪子 提交于 2019-12-12 19:52:01

问题


I have configured tests to run in parallel in Selenium with Nunit which works fine but I'm not sure how to add a custom method into the mix without a second instance of the browser opening and breaking the test.

I have the Base:

namespace ParallelTests
{
   public class Base
   {
       public IWebDriver Driver { get; set; }
   }
}

...and the Hooks:

public class Hooks : Base
{
   public Hooks()
   {
      Driver = new ChromeDriver(@"D:\Data\user\Documents\Visual Studio 2012\Projects\ParallelTests\ParallelTests\bin");
   }
}

...and a single test file:

[TestFixture]
[Parallelizable]
public class ChromeTesting: Hooks
{
    [Test]
    public void ChromegGoogleTest()
    {
        Driver.Navigate().GoToUrl("https://www.google.co.uk");
        Driver.FindElement(By.Id("lst-ib")).SendKeys("Deep Purple");
        Driver.FindElement(By.Id("lst-ib")).SendKeys(Keys.Enter);
    }
}

Running this works fine, but if I add a custom method, say:

public class ExtensionMethods : Hooks
{
    public void assertDisplayed()
    {
        Assert.IsTrue(Driver.FindElement(By.XPath("//*[contains(text(),'Some Text')]")).Displayed);
    }
}

and call assertDisplayed() in the test such as:

[TestFixture]
[Parallelizable]
public class ChromeTesting: Hooks
{
  [Test]
  public void ChromegGoogleTest()
  {
    Driver.Navigate().GoToUrl("https://www.google.co.uk");
    Driver.FindElement(By.Id("lst-ib")).SendKeys("Deep Purple");
    Driver.FindElement(By.Id("lst-ib")).SendKeys(Keys.Enter);
    ExtensionMethods.assertDisplayed();
  }
}

It will launch a second blank browser when I call assertDisplayed() in the test shown above. Any help much appreciated.

Now working based on suggestions but below is an example with page object model which again launches a second browser window...

Page File:

namespace ParallelTests
{
class PageObject_LoggedIn : Hooks
{
  public PageObject_LoggedIn()
  {
      PageFactory.InitElements(Driver, this);
  }

  [FindsBy(How = How.XPath, Using = @"//*[contains(text(),'Deep Purple | Official Site')]")]
  public IWebElement SearchText = null;

    [FindsBy(How = How.Id, Using = "lst-ib")]
    public IWebElement SearchBox = null;

    public void Search()
    {
        SearchBox.SendKeys("Deep Purple");
        SearchBox.SendKeys(Keys.Enter);
        Driver.assertDisplayed2();
    }
}

}

...and calling in the test... Test code:

[TestFixture]
[Parallelizable]
public class ChromeTesting: Hooks
{
    [Test]
    public void ChromegGoogleTest()
    {
        PageObject_LoggedIn loggedIn = new PageObject_LoggedIn();

        Driver.Navigate().GoToUrl("https://www.google.co.uk");
        loggedIn.Search();
    }
}

回答1:


Ok so there are a few things you need to change. Extension methods have a few rules which we need to follow. The rules are:

  1. It must be in a non generic static class. So the method must be static since you cannot have instance methods in a static class.
  2. It must have one parameter and the first parameter must have this keyword. The first parameter cannot have out or ref.
  3. The first parameter cannot be a pointer type.

So keeping those rules in mind, let's go ahead and create the extension method you need.

namespace ParallelTests
{
    public static class ExtensionMethods // I would call it ChromeDriverEntension
    {
        public static void AssertDisplayed(this IWebDriver driver)
        {
            Assert.IsTrue(driver.FindElement(By.XPath("//*[contains(text(),'Some Text')]")).Displayed);
        }
    }
} 

The above is a nongeneric static class. It has one parameter and the first parameter has this keyword. The first parameter is IWebDriver since this is what we are extending. The method is also static.

Ok let's go ahead and use it.

namespace ParallelTests
{
    public class Base
    {
        public IWebDriver Driver { get; set; }
    }

    public class Hooks : Base
    {
        public Hooks()
        {
            Driver = new ChromeDriver();
        }
    }

    [TestFixture]
    [Parallelizable]
    public class ChromeTesting : Hooks
    {
        [Test]
        public void ChromegGoogleTest()
        {
            Driver.Navigate().GoToUrl("https://www.google.co.uk");
            Driver.FindElement(By.Id("lst-ib")).SendKeys("Deep Purple");
            Driver.FindElement(By.Id("lst-ib")).SendKeys(Keys.Enter);
            Driver.AssertDisplayed();
        }
    }
}

How the compiler finds the extension method?

When the compiler notices code which looks like instance method, Driver.AssertDisplayed();, but there is no instance method that satisfies the signature, then it looks for an extension method. It searches all the namespaces to find a match. Since this method is in the same namespace above, it will find it. If it was in a different namespace, you would need to import that namespace with using A.B where A.B is the name of the namespace where the extension method is. Otherwise, the compiler will generate an error saying it cannot find such a method.

C# in Depth by Jon Skeet covers extension methods in depth if you want to read more.



来源:https://stackoverflow.com/questions/40952942/selenium-parallel-testing-with-extension-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!