asp.net - net - ¿Cómo puedo hacer que mis pruebas de Selenium sean menos frágiles?
razor if (7)
¿Cómo estás creando tus pruebas de Selenio, grabándolas y reproduziéndolas? Lo que hemos hecho es crear un modelo de objetos alrededor de las páginas para llamar a un método como "clickSubmit ()" en lugar de hacer clic en una identificación (con una convención de nomenclatura para estos identificadores), que permite que las pruebas de selenio sobrevivan a muchos cambios.
Usamos Selenium para probar la capa de interfaz de usuario de nuestra aplicación ASP.NET. Muchos de los casos de prueba prueban flujos más largos que abarcan varias páginas.
Descubrí que las pruebas son muy frágiles, rotas no solo por cambios de código que realmente cambian las páginas, sino también por refactorizaciones inocuas como cambiar el nombre de un control (ya que necesito pasar el ID de cliente del control al método Click de Selenium, etc.) o reemplazar una vista de cuadrícula con un repetidor. Como resultado, me encuentro "perdiendo" el tiempo actualizando los valores de cadena en mis casos de prueba para arreglar las pruebas rotas.
¿Hay alguna manera de escribir pruebas de Selenio más fáciles de mantener? ¿O una mejor herramienta de prueba de interfaz de usuario web?
Editado para agregar: Generalmente, el primer borrador se crea al grabar una prueba en el IDE. (Este primer paso puede ser realizado por el personal de control de calidad). Luego refactorizo el código C # generado (extrae constantes, extrae métodos para código repetido, tal vez repita el caso de prueba con datos diferentes, etc.). Pero el flujo general de código para cada caso de prueba permanece razonablemente cerca del código generado originalmente.
Creo que Xpath es la mejor manera de garantizar pruebas sólidas de selenio. Actualmente estoy trabajando en una biblioteca para ayudar a escribir expresiones xpath más fácil.
Si está interesado, puede consultarlo aquí: http://www.unit-testing.net/CurrentArticle/How-To-Write-XPath-for-Selenium-Tests.html
Descubrí que usar expresiones XPath en Selenuium-RC agrega mucho a la solidez de una prueba.
Escribo mis pruebas de manera similar. El primer paso a menudo se escribe a través de IDE / Record para obtener la mayor parte de mis operaciones de flujo de página y clic. Una vez que tengo eso, comienzo a pasar la prueba a través de Selenium-RC agregando aserciones y cambiando los localizadores de widgets absolutos a expresiones de Xpath más legibles y amigables. (¡además de documentar la prueba! :))
Una cosa a tener en cuenta ... si tus pruebas son pesadas xpath, pueden correr un poco más lento en IE6 debido a sus pobres habilidades de ejecución de javascript. (Tengo algunas suites de prueba que tardan casi una hora más en ejecutarse en IE que en FF. Es manejable, pero es algo a tener en cuenta cuando se escriben las pruebas).
El selenio en teoría tiene una abstracción llamada Elemento UI (la documentación está here ).
Las características serían
localizadores abstractos, independientes de la implementación de html; esto se correspondería bien con el concepto de componente o artilugio de un marco web,
reglas de resumen, lo que permite fusionar varios comandos en un único comando más abstracto.
He luchado un par de días para aprovechar esta característica, pero al final decidí abandonarla por las siguientes razones:
- algunos conceptos, como el de los localizadores de compensación (piensen en ellos como partes de un componente) no se desarrollan de manera completa o útil;
- la característica no es totalmente compatible con los formateadores y cuanto más reciente sea el formateador, menos se admite la función, lo que sugiere que la evolución central del Selenio está dejando atrás esta característica;
- no está completamente integrado en Selenium 2.0 (WebDriver).
He encontrado el patrón de PageObject muy útil.
http://code.google.com/p/webdriver/wiki/PageObjects
más información: - ¿Cuál es el punto del selenio? - Crítica de selenio
tal vez una buena forma de comenzar es refactorizar incrementalmente sus casos de prueba.
Yo uso el mismo escenario que tiene selenio + c #
Así es como se ve mi código:
Un método de prueba se parecerá a algo así como esto
[TestMethod]
public void RegisterSpecialist(UserInfo usrInfo, CompanyInfo companyInfo)
{
var RegistrationPage = new PublicRegistrationPage(selenium)
.FillUserInfo(usrInfo)
.ContinueSecondStep();
RegistrationPage.FillCompanyInfo(companyInfo).ContinueLastStep();
RegistrationPage.FillSecurityInformation(usrInfo).ContinueFinishLastStep();
Assert.IsTrue(RegistrationPage.VerifySpecialistRegistrationMessagePayPal());
selenium.WaitForPageToLoad(Resources.GlobalResources.TimeOut);
paypal.LoginSandboxPage(usrInfo.sandboxaccount, usrInfo.sandboxpwd);
Assert.IsTrue(paypal.VerifyAmount(usrInfo));
paypal.SubmitPayment();
RegistrationPage.GetSpecialistInformation(usrInfo);
var bphome = new BPHomePage(selenium, string.Format(Resources.GlobalResources.LoginBPHomePage, usrInfo.AccountName, usrInfo.Password));
Assert.IsTrue(bphome.VerifyPageWasLoaded(usrInfo));
Assert.IsTrue(bphome.VerifySpecialistProfile());
bphome.Logout();
}
Un objeto de página será algo como esto
public class PublicRegistrationPage
{
public ISelenium selenium { get; set; }
#region Constructors
public PublicRegistrationPage(ISelenium sel)
{
selenium = sel;
selenium.Open(Resources.GlobalResources.PublicRegisterURL);
}
#endregion
#region Methods
public PublicRegistrationPage FillUserInfo(UserInfo usr)
{
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserFirstName", usr.FirstName);
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserLastName", usr.LastName);
selenium.Select("ctl00_cphComponent_ctlContent_wizRegister_ddlUserCountry", string.Format("label={0}",usr.Country ));
selenium.WaitForPageToLoad(Resources.GlobalResources.TimeOut);
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserEmail", usr.Email );
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserDirectTel", usr.DirectTel);
selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserMobile", usr.Mobile);
return this;
}
}
Espero que esto ayude.
No hay cambios inocuos en lo que respecta a la automatización de pruebas;)
Usamos el marco SAFS con Rational Robot (RRAFS) para minimizar el impacto en nuestros scripts de automatización. Todavía hay trabajo para mantener el mapa de la aplicación, pero los scripts permanecen estables en su mayor parte. El marco SAFS suena muy similar al método que menciona cynicalman, pero ya empaqueta los métodos genéricos que usaría en sus scripts.
El sitio de SAFS dice que hay apoyo parcial para Selenium, por lo que esto puede funcionar para usted.
Puede o no puede escribir pruebas que sean resistentes a la refactorización. He aquí cómo hacer que la refactorización sea menos dolorosa: la integración continua es esencial.
Ejecútelos todos los días o cada compilación. Cuanto antes se solucione, más fácil.
Asegúrese de que los desarrolladores puedan ejecutar las pruebas ellos mismos. De nuevo, cuanto antes se lo vea y lo arregle, más fácil será.
Mantenga las pruebas de selenio pocos. Deben enfocarse en escenarios de prueba de ruta crítica / pri 1. Las pruebas profundas se deben realizar a nivel de prueba unitaria (o jsunit tests). Las pruebas de integración siempre son costosas y menos valiosas.