2011-01-27 12 views
9

Sto cercando un modo per riutilizzare una suite di test NUnit senza duplicare l'intera suite per ciascun browser. Sembra che avrei bisogno di un nuovo apparecchio per ogni browser. Posso inviare una sorta di variabile di ambiente o di configurazione dalla GUI NUnit per cambiare il browser? vedi sotto:Come posso testare più browser con selenio e una singola suite NUnit e tenerlo ASCIUTTO?

[TestFixture] 
public class User 
{ 
    private ISelenium selenium; 
    private StringBuilder verificationErrors; 

    [SetUp] 
    public void SetupTest() 
    { 
     // TheBrowser = How do I populate this variable from the NUnit gui? 
     selenium = new DefaultSelenium("localhost", 4444, **TheBrowser**, "http://localhost:52251/"); 
     selenium.Start(); 
     verificationErrors = new StringBuilder(); 
    } 

    [TearDown] 
    public void TeardownTest() 
    { 
     ... 
    } 

    [Test] 
    public void SearchUser() 
    { 
     ... 
    } 

} 

risposta

4

Buona domanda, molte persone si imbattono in questo problema. Sono un fan di iniettare il mio browser nel mio caso di test utilizzando un contenitore IoC. Ciò mi consente di inserire tutta la configurazione del mio browser in un'iniezione "mudule"

Io uso i binding Java e Guice come mio contenitore IoC, ma i principal sono gli stessi in .Net. Vuoi un campo DefaultSelnium nella tua classe che viene iniettato. I tuoi test quindi utilizzano questo oggetto e lo eliminano quando hanno finito. Potresti scoprire di poterlo iniettare subito, oppure potresti aver bisogno di fare la creazione dell'oggetto in un metodo di installazione. Alcune cose da tenere a mente, a seconda del framework di test dell'unità:

  • Le classi di test sono state create nuove per ciascun test? JUnit crea una nuova istanza della classe di test per ogni test da eseguire. TestNG ha notoriamente eliminato questo oggetto riutilizzando gli oggetti di classe per ogni test contenuto. Il problema con il riutilizzo è l'istanza DefaultSelenium iniettata che viene gestita per la corsa, il che potrebbe causare problemi se i test vengono eseguiti in parallelo o se si modifica lo stato del browser.
  • Pigro Carica l'oggetto del browser Se il tuo strumento di test delle unità carica tutte le classi di test immediatamente, cercherà di creare gli oggetti del browser in primo piano, il che è piuttosto impegnativo in termini di risorse.

Sono sicuro che puoi Google per te stesso meglio di me, ma questi sono alcuni collegamenti DI e NUnit che pensavo promettessero.

NUnit integration tests and dependency injection

http://buildstarted.com/2010/08/24/dependency-injection-with-ninject-moq-and-unit-testing/

Se non ti piace DI ho sentito parlare di persone che utilizzano metodi di fabbrica per generare il proprio browser in base a qualche sistemazione esterna.

5

NUnit 2.5+ supporta dispositivi di prova generici che rendono molto semplice la verifica in più browser. http://www.nunit.org/index.php?p=testFixture&r=2.5

La creazione di quanto segue creerà due test NUnit "GoogleTest", uno per Firefox e uno per IE.

using NUnit.Framework; 
using OpenQA.Selenium; 
using OpenQA.Selenium.Firefox; 
using OpenQA.Selenium.IE; 
using System.Threading; 

namespace SeleniumTests 
{ 
    [TestFixture(typeof(FirefoxDriver))] 
    [TestFixture(typeof(InternetExplorerDriver))] 
    public class TestWithMultipleBrowsers<TWebDriver> where TWebDriver : IWebDriver, new() 
    { 
     private IWebDriver driver; 

     [SetUp] 
     public void CreateDriver() { 
      this.driver = new TWebDriver(); 
     } 

     [Test] 
     public void GoogleTest() { 
      driver.Navigate().GoToUrl("http://www.google.com/"); 
      IWebElement query = driver.FindElement(By.Name("q")); 
      query.SendKeys("Bread" + Keys.Enter); 

      Thread.Sleep(2000); 

      Assert.AreEqual("bread - Google Search", driver.Title); 
      driver.Quit(); 
     } 
    } 
} 
2

Ecco un test di esempio unità utilizzando una consuetudine xUnit DataAttribute per fornire il driver alla prova

using OpenQA.Selenium; 
using SeleniumPageObjectsPatternExample.Attributes; 
using SeleniumPageObjectsPatternExample.PageObjects; 
using Xunit; 
using Xunit.Extensions; 

public class HomepageTests 
{ 
    [Theory] 
    [Browser(Type.Firefox)] 
    [Browser(Type.GoogleChrome)] 
    public void HomepageLinksToBlogPage(IWebDriver webDriver) 
    { 
     // arrange 
     var expected = "some expected value"; 

     // act 
     var homepage = new HomePage(webDriver, true); 

     // assert 
     Assert.True(homepage.BlogLink.Displayed); 
     Assert.Equal(expected, homepage.Header.Text); 
    } 
} 

Ecco l'abitudine DataAttribute

using System.Reflection; 
using OpenQA.Selenium; 
using SeleniumPageObjectsPatternExample.WebDriver; 
using Xunit.Extensions; 

public class BrowserAttribute : DataAttribute 
{ 
    private IWebDriver WebDriver { get; set; } 

    public BrowserAttribute(Type browser) 
    { 
     this.WebDriver = WebDriverFactory.Create(browser); 
    } 

    public override IEnumerable<object[]> GetData(MethodInfo methodUnderTest, System.Type[] parameterTypes) 
    { 
     return new[] { new[] { this.WebDriver } }; 
    } 
} 

Usando questo WebDriverFactory

using OpenQA.Selenium; 
using OpenQA.Selenium.Chrome; 
using OpenQA.Selenium.Firefox; 

using Type = SeleniumPageObjectsPatternExample.Attributes.Type; 

public class WebDriverFactory 
{ 
    public static IWebDriver Create(Type browser) 
    { 
     IWebDriver webDriver; 

     switch (browser) 
     { 
      case Type.Firefox: 
       webDriver = new FirefoxDriver(); 
       break; 
      case Type.GoogleChrome: 
       webDriver = new ChromeDriver(); 
       break; 
      default: 
       webDriver = new ChromeDriver(); 
       break; 
     } 

     webDriver.Manage().Window.Maximize(); 

     return webDriver; 
    } 
} 

E il tipo di browser enum

public enum Type 
{ 
    Firefox, 
    GoogleChrome 
} 

vi consiglio di cambiare il nome del enum da tipo a qualcos'altro ...

1

vi consiglio una variazione importante soluzione di Lucifero. L'attributo fornisce una fabbrica, non un driver, ai metodi Fact/Theory. Perché? Bene, quando vedi tutte quelle finestre del browser pop-up (n x m, dove n = numero di test, m = browser per test), decidi che vuoi solo che vengano creati quando il test sta effettivamente andando correre.

Quindi, con gli aggiornamenti da soluzione prima, tra cui alcuni cambi di nome ...

using OpenQA.Selenium; 
using SeleniumPageObjectsPatternExample.Attributes; 
using SeleniumPageObjectsPatternExample.PageObjects; 
using Xunit; 
using Xunit.Extensions; 

namespace SeleniumHelpers 
{  
    public class HomepageTests 
    { 
     [Theory] 
     [WebDriver(DriverType.Firefox)] 
     [WebDriver(DriverType.GoogleChrome)] 
     public void HomepageLinksToBlogPage(WebDriverFactory factory) 
     { 
      // arrange 
      IWebDriver webDriver = factory.Create(); // Browser starts here. 
      var expected = "some expected value"; 

      // act 
      var homepage = new HomePage(webDriver, true); 

      // assert 
      Assert.True(homepage.BlogLink.Displayed); 
      Assert.Equal(expected, homepage.Header.Text); 

      // Optional cleanup (better wrapped in try/finally for entire method). 
      webDriver.Quit(); 
      webDriver.Dispose(); 
     } 
    } 
} 

Aggiornato DataAttribute ... (Nota, ho corretto la firma del metodo GetData() per lavorare con l'ultima xUnit.)

using System.Reflection; 
using OpenQA.Selenium; 
using Xunit.Extensions; 

namespace SeleniumHelpers 
{  
    public class WebDriverAttribute : DataAttribute 
    { 
     private WebDriverFactory WebDriverFactory { get; set; } 

     public WebDriverAttribute(Type browser) 
     { 
      this.WebDriver = WebDriverFactory.Create(browser); 
     } 

     public override IEnumerable<object[]> GetData(MethodInfo methodUnderTest) 
     { 
      return new[] { new[] { this.WebDriverFactory } }; 
     } 
    } 
} 

Il nuovo WebDriverFactory

using OpenQA.Selenium; 
using OpenQA.Selenium.Chrome; 
using OpenQA.Selenium.Firefox; 

namespace SeleniumHelpers 
{  
    public enum DriverType 
    { 
     Firefox, 
     GoogleChrome 
    } 

    public class WebDriverFactory 
    { 
     private DriverType _driverType; 
     public WebDriverFactory(DriverType driverType) 
     { 
      _driverType = driverType; 
     } 

     public static IWebDriver Create(Type browser) 
     { 
      IWebDriver webDriver; 

      switch (browser) 
      { 
       case Type.Firefox: 
        webDriver = new FirefoxDriver(); 
        break; 
       case Type.GoogleChrome: 
        webDriver = new ChromeDriver(); 
        break; 
       default: 
        webDriver = new ChromeDriver(); 
        break; 
      } 

      webDriver.Manage().Window.Maximize(); 

      return webDriver; 
     } 
    } 
} 
Problemi correlati