2011-01-27 12 views
9

Estoy buscando una forma de reutilizar un conjunto de pruebas NUnit sin duplicar el conjunto completo para cada navegador. Parece que necesitaría un nuevo accesorio para cada navegador. ¿Puedo enviar algún tipo de variable de entorno o configuración desde la interfaz de usuario de NUnit para cambiar de navegador? vea a continuación:¿Cómo pruebo múltiples navegadores con selenio y una única suite NUnit y lo mantengo SECO?

[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() 
    { 
     ... 
    } 

} 

Respuesta

4

Buena pregunta, mucha gente se encuentra con este problema. Soy fanático de inyectar mi navegador en mi caso de prueba usando un contenedor IoC. Eso me permite poner toda la configuración de mi navegador en una inyección 'mudule'

Utilizo los enlaces de Java y Guice como mi Contenedor de IoC, pero los principios son los mismos en .Net. Desea que se inyecte un campo DefaultSelnium en su clase. Tus pruebas luego usan este objeto y lo tiran cuando terminan. Puede descubrir que puede inyectarlo de inmediato, o puede necesitar hacer la creación del objeto en un método de configuración. Unas pocas cosas que usted debe mirar hacia fuera para, en función de su marco de pruebas de unidad:

  • Están sus clases de prueba creado nuevas para cada prueba? JUnit crea una nueva instancia de la clase de prueba para cada prueba que se ejecutará. Probablemente, TestNG eliminó este objeto y reutiliza los objetos de la clase de prueba para cada prueba contenida. El problema con la reutilización es que la instancia de DefaultSelenium inyectada se utiliza para el viaje, lo que podría ocasionar problemas si las pruebas se ejecutan en paralelo o cambiar el estado del navegador.
  • Lazy Cargue su objeto de navegador Si su herramienta de prueba de la Unidad carga todas las clases de prueba desde el principio, intentará crear los objetos del navegador por adelantado, lo cual requiere bastante recursos.

Estoy seguro de que puedes buscar por ti mismo mejor que yo, pero estos son algunos enlaces de DI y NUnit que pensé que parecían prometedores.

NUnit integration tests and dependency injection

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

Si no te gusta DI He oído de personas que utilizan métodos de fábrica para generar su navegador basado en alguna configuración externa.

5

NUnit 2.5+ admite accesorios de prueba genéricos que hacen que las pruebas en varios navegadores sean muy sencillas. http://www.nunit.org/index.php?p=testFixture&r=2.5

Al crear lo siguiente, se crearán dos pruebas NUnit "GoogleTest", una para Firefox y otra para 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

Aquí es una prueba de ejemplo unidad utilizando una costumbre XUnit DataAttribute para proporcionar al conductor a la prueba

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); 
    } 
} 

Aquí es costumbre 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 } }; 
    } 
} 

El uso de este 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; 
    } 
} 

Y el tipo de navegador enumeración

public enum Type 
{ 
    Firefox, 
    GoogleChrome 
} 

Yo aconsejaría que cambie el nombre de la enumeración de un tipo a otra cosa ...

1

recomiendo una variación importante en la solución de Lucifer. Haga que el atributo suministre una fábrica, no un controlador, a los métodos de Hecho/Teoría. ¿Por qué? Bueno, cuando veas todas las ventanas emergentes del navegador (n x m, donde n = número de pruebas, m = navegadores por prueba), decidirás que solo quieres que se creen cuando la prueba vaya realmente correr.

Así que con las actualizaciones de la solución anterior, incluyendo algunos cambios de nombre ...

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(); 
     } 
    } 
} 

Actualizado DataAttribute ... (Nota, he corregido la firma del método GetData() para trabajar con la última 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 } }; 
     } 
    } 
} 

El nuevo 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; 
     } 
    } 
} 
Cuestiones relacionadas