2011-02-17 22 views
29

Estoy buscando la mejor forma recomendada para que las pruebas de Selenium se ejecuten en varios navegadores uno tras otro. El sitio web que estoy probando no es grande, por lo que aún no necesito una solución paralela.Ejecute las pruebas de Selenio en varios navegadores uno tras otro desde C# NUnit

Tengo los métodos de configuración de prueba habituales con [SetUp], [TearDown] y [Test]. El SetUp uno, por supuesto, ejemplifica un nuevo objeto ISelenium con cualquier navegador con el que quiera probar.

Entonces, lo que quiero hacer es decir programáticamente: esta prueba se ejecutará en Chrome, IE y Firefox en secuencia. ¿Cómo puedo hacer eso?

EDITAR:

Esto podría ayudar un poco. Estamos usando CruiseControl.NET para comenzar las pruebas de NUnit después de una compilación exitosa. ¿Hay alguna forma de pasar un parámetro al ejecutable de NUnit y luego usar ese parámetro en la prueba? De esta forma podríamos ejecutar NUnit varias veces con diferentes parámetros del navegador.

Respuesta

50

NUnit 2.5+ ahora es compatible con Dispositivos para ensayos genéricos que hacen la prueba en varios navegadores muy sencillo. http://www.nunit.org/index.php?p=testFixture&r=2.5

Ejecutar el siguiente ejemplo ejecutará GoogleTest dos veces, una en Firefox y otra en 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(); 
     } 
    } 
} 
+0

esta es la mejor respuesta –

+0

@alanning No puedo hacer que mi sistema reconozca dónde se encuentra el controlador para IE, ¿dónde debo ubicarlo para que se ejecute? – DEnumber50

+1

@ DEnumber50 Ha pasado un tiempo desde que trabajé con esto, pero https://code.google.com/p/selenium/wiki/InternetExplorerDriver dice que el archivo ejecutable debe estar en su ruta. También tenga en cuenta la configuración requerida para IE11 si está utilizando eso. – alanning

0

Hay debe haber una mejor manera, pero se puede usar para generar T4 templates clases de prueba por duplicado para cada navegador - la automatización esencialmente una copia y pegar de las pruebas para cada navegador.

+0

Sí, tiene que haber una mejor manera. – Edgar

1

Bien, una solución es tener pruebas contenedoras que configuren el objeto ISelenium con diferentes navegadores. Luego pasan ese objeto a todas las otras pruebas que lo usan en lugar de configurar uno nuevo como lo hicieron anteriormente.

La desventaja es que termino con una gran prueba para cada navegador. No es la mejor solución tampoco. Todavía estás ...

EDIT:

pasado algún más tiempo en esto. La solución que se me ocurrió es tener un archivo de texto en la solución que especifique el navegador que se utilizará para las pruebas. NUnit recupera la configuración al crear una instancia de un objeto Selenium.

Estoy usando CruiseControl.NET para ejecutar compilaciones y pruebas automáticas. Y en lugar de simplemente ejecutar la prueba una vez, la configuré para ejecutarla dos veces. Pero antes de cada prueba ejecuto un comando de línea de comando que cambia el navegador en el archivo de texto de configuración.

<exec> 
    <executable>cmd</executable> 
    <buildArgs>/C echo firefox C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe > F:\...\selenium_browser.txt</buildArgs> 
</exec> 
<exec> 
    <executable>F:\...\NUnit 2.5.7\bin\net-2.0\nunit-console.exe</executable> 
    <baseDirectory>F:\...\bin\Debug</baseDirectory> 
    <buildArgs>F:\...\...nunit /xml:"F:\CCXmlLog\Project\nunit-results.xml" /noshadow</buildArgs> 
    <successExitCodes>0</successExitCodes> 
    <buildTimeoutSeconds>1200</buildTimeoutSeconds> 
</exec> 

<exec> 
    <executable>cmd</executable> 
    <buildArgs>/C echo googlechrome C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe > F:\...\selenium_browser.txt</buildArgs> 
</exec> 
<exec> 
    <executable>F:\...\NUnit 2.5.7\bin\net-2.0\nunit-console.exe</executable> 
    <baseDirectory>F:\...\bin\Debug</baseDirectory> 
    <buildArgs>F:\...\...nunit /xml:"F:\CCXmlLog\Project\nunit-results.xml" /noshadow</buildArgs> 
    <successExitCodes>0</successExitCodes> 
    <buildTimeoutSeconds>1200</buildTimeoutSeconds> 
</exec> 
+0

Resulta que también puede especificar variables de entorno con el elemento '', por lo que sería una forma de evitar los archivos de texto. – Edgar

5

Esta es una pregunta que se repite y se resuelve un par de maneras:

  1. método de fábrica produce su objeto ISelenium - Usted tiene una clase de ayuda con un método getSelenium estática. Ese método se lee en una configuración externa, que tiene una propiedad que define el navegador que desea como una cadena. En su getSelenium, entonces configura el navegador en consecuencia. aquí hay una publicación útil sobre el uso de archivos de configuración con NUnit http://blog.coryfoy.com/2005/08/nunit-app-config-files-its-all-about-the-nunit-file/

  2. Otros tienen éxito al inyectar el navegador a través de un contenedor IoC. Me gusta mucho porque TestNG funciona muy bien con Guice en Java, pero no estoy seguro de lo fácil que es mezclar NUnit y Ninject, MEF, etc.

+0

Tengo las cosas de ayuda y la cadena configurable del navegador, pero el problema es que tengo que ejecutar la misma prueba varias veces con diferentes navegadores. – Edgar

+0

Entonces deberías estar intercambiando los archivos de configuración para cada ejecución. El archivo de configuración completo sería el mismo, pero tendría el nombre del navegador como una cadena para cada navegador que quisiera probar. – pnewhook

4

utilizo una lista de controlador IWeb para realizar pruebas en todos los navegadores, línea por línea:

[ClassInitialize] 
     public static void ClassInitialize(TestContext context) { 
      drivers = new List<IWebDriver>(); 
      firefoxDriver = new FirefoxDriver(); 
      chromeDriver = new ChromeDriver(path); 
      ieDriver = new InternetExplorerDriver(path); 
      drivers.Add(firefoxDriver); 
      drivers.Add(chromeDriver); 
      drivers.Add(ieDriver); 
      baseURL = "http://localhost:4444/"; 
     } 

    [ClassCleanup] 
    public static void ClassCleanup() { 
     drivers.ForEach(x => x.Quit()); 
    } 

..and then am able to write tests like this: 

[TestMethod] 
     public void LinkClick() { 
      WaitForElementByLinkText("Link"); 
      drivers.ForEach(x => x.FindElement(By.LinkText("Link")).Click()); 
      AssertIsAllTrue(x => x.PageSource.Contains("test link")); 
     } 

..where Estoy escribiendo mis propios métodos y WaitForElementByLinkText AssertIsAllTrue para realizar la operación para cada conductor, y donde todo falla, para que envíe un mensaje ayudarme a identificar qué navegador (s) puede haber fallado:

public void WaitForElementByLinkText(string linkText) { 
      List<string> failedBrowsers = new List<string>(); 
      foreach (IWebDriver driver in drivers) { 
       try { 
        WebDriverWait wait = new WebDriverWait(clock, driver, TimeSpan.FromSeconds(5), TimeSpan.FromMilliseconds(250)); 
        wait.Until((d) => { return d.FindElement(By.LinkText(linkText)).Displayed; }); 
       } catch (TimeoutException) { 
        failedBrowsers.Add(driver.GetType().Name + " Link text: " + linkText); 
       } 
      } 
      Assert.IsTrue(failedBrowsers.Count == 0, "Failed browsers: " + string.Join(", ", failedBrowsers)); 
     } 

El IEDriver es dolorosamente lento, pero esto tendrá 3 o f los navegadores principales ejecutan pruebas 'uno al lado del otro'

5

Esto es básicamente una expansión de la respuesta de Alanning (21 de octubre de 2011 a las 20:20). Mi caso fue similar, solo que no quería ejecutar con el constructor sin parámetros (y así utilizar la ruta predeterminada para los ejecutables del controlador). Tenía una carpeta separada que contiene los controladores que quería probar en contra, y esto parece funcionar muy bien:

[TestFixture(typeof(ChromeDriver))] 
[TestFixture(typeof(InternetExplorerDriver))] 
public class BrowserTests<TWebDriver> where TWebDriver : IWebDriver, new() 
{ 
    private IWebDriver _webDriver; 

    [SetUp] 
    public void SetUp() 
    { 
     string driversPath = Environment.CurrentDirectory + @"\..\..\..\WebDrivers\"; 

     _webDriver = Activator.CreateInstance(typeof (TWebDriver), new object[] { driversPath }) as IWebDriver; 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     _webDriver.Dispose(); // Actively dispose it, doesn't seem to do so itself 
    } 

    [Test] 
    public void Tests() 
    { 
     //TestCode 
    } 
} 

}

+0

+1 Brillante - esto es mucho más limpio y solo necesitas decorar tu clase con los diferentes controladores. – Deano

+0

¿Hay alguna forma de heredar esta clase para evitar el código redundante en cada clase de prueba? – bit

+0

No sé cómo funciona el atributo TestFixture con la herencia, pero todo dentro de SetUp y TearDown debería ser posible para pasar a otra clase y dejar que tus pruebas solo llamen a "GetWebDriver" o algo así. Supongo que podrías tratar de heredar de esta clase y ver qué pasa. –

1

Me preguntaba sobre el mismo tema y finalmente i got solution

Así Cuando instala el complemento, puede controlar en qué navegador se debe probar el escenario.

ejemplo Característica:

@Browser:IE 
@Browser:Chrome 
Scenario Outline: Add Two Numbers 
    Given I navigated to/
    And I have entered <SummandOne> into summandOne calculator 
    And I have entered <SummandTwo> into summandTwo calculator 
    When I press add 
    Then the result should be <Result> on the screen 
    Scenarios: 
     | SummandOne | SummandTwo | Result | 
     | 50 | 70 | 120 | 
     | 1 | 10 | 11 | 

Implementación

[Given(@"I have entered '(.*)' into the commentbox")] 
public void GivenIHaveEnteredIntoTheCommentbox(string p0) 
{ 
      Browser.Current.FindElement(By.Id("comments")).SendKeys(p0); 
} 

More info

+0

@Dukeling arreglado –

Cuestiones relacionadas