Prueba De Aplicaciones Web con Selenium 2 y WebDriver

13,501 views

Published on

Con Selenium 2.0 y Webdriver la ejecución de TDD y BDD se ve beneficiado por las fortalezas de ambos proyectos.

Introduciremos el API Java basado en PageObjects y veremos ejemplos de creación de pruebas cross-browser para un interfaz de aplicación web con Ajax

Published in: Education
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
13,501
On SlideShare
0
From Embeds
0
Number of Embeds
308
Actions
Shares
0
Downloads
352
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • Pruebas Unitarias.\n Componentes aislados del entorno\n Dependencias (Dobles de prueba)\n Framework.\n Pruebas de Integración\n Componentes trabajando en colaboración\n Infraestructura simplificada (BD, Sistemas externos...)\n Pruebas end-to-end\n La aplicación completa. Desde la visión del usuario.\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • No funciona con Frame Busters.\n
  • Spaghetti code.\n
  • Spaghetti code.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • HtmlUnit\nthe fastest and most lightweight \nPure Java Implementation.\nUses Rhino as its JavaScript+DOM implementation\nJavaScript disabled by Default. (emulate IE when enabled)\nCould emulate other brorwsers:\nHtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3)\n\nFirefox\nThe Firefox driver is the most mature of the browser-based drivers.\nInternet Explorer\nWork on IE6, IE7 and IE8 on WXP & Vista. \nCompared the other drivers, it is relatively slow.\nChrome\nis based on Webkit, you may be able to verify that your application works in other Webkit-based browsers such as Safari\nUses V8 JavaScript engine rather than the Safari Nitro engine, you may experience some differences in behavior\n
  • HtmlUnit\nthe fastest and most lightweight \nPure Java Implementation.\nUses Rhino as its JavaScript+DOM implementation\nJavaScript disabled by Default. (emulate IE when enabled)\nCould emulate other brorwsers:\nHtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3)\n\nFirefox\nThe Firefox driver is the most mature of the browser-based drivers.\nInternet Explorer\nWork on IE6, IE7 and IE8 on WXP & Vista. \nCompared the other drivers, it is relatively slow.\nChrome\nis based on Webkit, you may be able to verify that your application works in other Webkit-based browsers such as Safari\nUses V8 JavaScript engine rather than the Safari Nitro engine, you may experience some differences in behavior\n
  • HtmlUnit\nthe fastest and most lightweight \nPure Java Implementation.\nUses Rhino as its JavaScript+DOM implementation\nJavaScript disabled by Default. (emulate IE when enabled)\nCould emulate other brorwsers:\nHtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3)\n\nFirefox\nThe Firefox driver is the most mature of the browser-based drivers.\nInternet Explorer\nWork on IE6, IE7 and IE8 on WXP & Vista. \nCompared the other drivers, it is relatively slow.\nChrome\nis based on Webkit, you may be able to verify that your application works in other Webkit-based browsers such as Safari\nUses V8 JavaScript engine rather than the Safari Nitro engine, you may experience some differences in behavior\n
  • HtmlUnit\nthe fastest and most lightweight \nPure Java Implementation.\nUses Rhino as its JavaScript+DOM implementation\nJavaScript disabled by Default. (emulate IE when enabled)\nCould emulate other brorwsers:\nHtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3)\n\nFirefox\nThe Firefox driver is the most mature of the browser-based drivers.\nInternet Explorer\nWork on IE6, IE7 and IE8 on WXP & Vista. \nCompared the other drivers, it is relatively slow.\nChrome\nis based on Webkit, you may be able to verify that your application works in other Webkit-based browsers such as Safari\nUses V8 JavaScript engine rather than the Safari Nitro engine, you may experience some differences in behavior\n
  • HtmlUnit\nthe fastest and most lightweight \nPure Java Implementation.\nUses Rhino as its JavaScript+DOM implementation\nJavaScript disabled by Default. (emulate IE when enabled)\nCould emulate other brorwsers:\nHtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3)\n\nFirefox\nThe Firefox driver is the most mature of the browser-based drivers.\nInternet Explorer\nWork on IE6, IE7 and IE8 on WXP & Vista. \nCompared the other drivers, it is relatively slow.\nChrome\nis based on Webkit, you may be able to verify that your application works in other Webkit-based browsers such as Safari\nUses V8 JavaScript engine rather than the Safari Nitro engine, you may experience some differences in behavior\n
  • HtmlUnit\nthe fastest and most lightweight \nPure Java Implementation.\nUses Rhino as its JavaScript+DOM implementation\nJavaScript disabled by Default. (emulate IE when enabled)\nCould emulate other brorwsers:\nHtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3)\n\nFirefox\nThe Firefox driver is the most mature of the browser-based drivers.\nInternet Explorer\nWork on IE6, IE7 and IE8 on WXP & Vista. \nCompared the other drivers, it is relatively slow.\nChrome\nis based on Webkit, you may be able to verify that your application works in other Webkit-based browsers such as Safari\nUses V8 JavaScript engine rather than the Safari Nitro engine, you may experience some differences in behavior\n
  • HtmlUnit\nthe fastest and most lightweight \nPure Java Implementation.\nUses Rhino as its JavaScript+DOM implementation\nJavaScript disabled by Default. (emulate IE when enabled)\nCould emulate other brorwsers:\nHtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3)\n\nFirefox\nThe Firefox driver is the most mature of the browser-based drivers.\nInternet Explorer\nWork on IE6, IE7 and IE8 on WXP & Vista. \nCompared the other drivers, it is relatively slow.\nChrome\nis based on Webkit, you may be able to verify that your application works in other Webkit-based browsers such as Safari\nUses V8 JavaScript engine rather than the Safari Nitro engine, you may experience some differences in behavior\n
  • HtmlUnit\nthe fastest and most lightweight \nPure Java Implementation.\nUses Rhino as its JavaScript+DOM implementation\nJavaScript disabled by Default. (emulate IE when enabled)\nCould emulate other brorwsers:\nHtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3)\n\nFirefox\nThe Firefox driver is the most mature of the browser-based drivers.\nInternet Explorer\nWork on IE6, IE7 and IE8 on WXP & Vista. \nCompared the other drivers, it is relatively slow.\nChrome\nis based on Webkit, you may be able to verify that your application works in other Webkit-based browsers such as Safari\nUses V8 JavaScript engine rather than the Safari Nitro engine, you may experience some differences in behavior\n
  • HtmlUnit\nthe fastest and most lightweight \nPure Java Implementation.\nUses Rhino as its JavaScript+DOM implementation\nJavaScript disabled by Default. (emulate IE when enabled)\nCould emulate other brorwsers:\nHtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_3)\n\nFirefox\nThe Firefox driver is the most mature of the browser-based drivers.\nInternet Explorer\nWork on IE6, IE7 and IE8 on WXP & Vista. \nCompared the other drivers, it is relatively slow.\nChrome\nis based on Webkit, you may be able to verify that your application works in other Webkit-based browsers such as Safari\nUses V8 JavaScript engine rather than the Safari Nitro engine, you may experience some differences in behavior\n
  • \n\n
  • \n\n
  • \n\n
  • \n
  • \n
  • \n
  • Representan fragmentos de la página\n Implementan sus operaciones\n
  • Representan fragmentos de la página\n Implementan sus operaciones\n
  • Representan fragmentos de la página\n Implementan sus operaciones\n
  • Representan fragmentos de la página\n Implementan sus operaciones\n
  • Representan fragmentos de la página\n Implementan sus operaciones\n
  • Representan fragmentos de la página\n Implementan sus operaciones\n
  • boolean toggle();\n boolean isSelected();\n void setSelected();\n boolean isEnabled();\n String getText();\n\n
  • Drag ‘n’ drop y hover es mejor a través del\nAdvanced User Interactions API\n\n ActionChainsGenerator builder = ((HasInputDevices) driver).actionsBuilder();\n   builder.keyDown(Keys.CONTROL)\n       .click(someElement)\n       .click(someOtherElement)\n .clickAndHold(someElement)\n       .keyUp(Keys.CONTROL);\n builder.build();\n builder.permform();\n\n\n\n
  • Aquí es donde empieza lo bueno.\n
  • Todas las ventajas de OO\n \n
  • \n
  • \n
  • Convention over Configuration:\n Constructor sin argumentos o con WebDriver\n Atributos WebElement buscados por id\n
  • \n
  • getShow y clickOnShow encapsulan la funcionalidad de la página.\n
  • /** Allows injection of specific driver to test with a different browser engine */\n\nEl test showDetail() utiliza el API de KoliseoHomePage.\n\nPageObject no debería hacer Asserts\n
  • Los componentes encapsulan la carga en el método get().\n\n
  • KoliseoHomePage reescrito como LoadableComponent\nAparentemente no hemos ganado mucho....\n
  • \n
  • \n
  • El componente de login busca la home, \n pincha en el link de login\n Rellena el formulario y lo envía\n
  • La página protegida\n Carga el Login (si ya se ha hecho login no se rehace)\n
  • \n
  • \n
  • \n
  • \n
  • Prueba De Aplicaciones Web con Selenium 2 y WebDriver

    1. 1. http://extrema-sistemas.comPrueba de aplicaciones web conSelenium 2 y WebDriverDavid Gómez
    2. 2. Pruebas de aplicaciones webPruebas unitarias.Pruebas de integración.Pruebas end-to-end. 2
    3. 3. Pruebas end-to-endLa visión del usuarioDistintos navegadoresRich Web Applications - Ajax y JavaScript 3
    4. 4. SeleniumHerramienta para pruebas funcionales desde la perspectiva del usuario. 4
    5. 5. ComponentesSelenium Core - Motor de ejecución empotrado en el NavegadorSelenium IDE - Herramienta para grabar los tests en HTMLSelenium RC (Remote Control) - Tests escritos en Java, Ruby, Python, Perl, PHP... 5
    6. 6. Selenium IDE FireFox plugin que graba y ejecuta los tests. 6
    7. 7. SeleniumTest Cases y Test Suites en formato HTML. 7
    8. 8. SeleniumTest Cases y Test Suites en formato HTML. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta content="text/html; charset=UTF-8" http-equiv="content-type" /> <title>Test Suite</title> </head> <body> <table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"> <tbody> <tr><td><b>Test Suite</b></td></tr> <tr><td><a href="CreateShowTest">CreateShowTest</a></td></tr> <tr><td><a href="DeleteShowTest">DeleteShowTest</a></td></tr> </tbody> </table> </body> </html> 7
    9. 9. SeleniumTest Cases y Test Suites en formato HTML. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <body> <head> cellpadding="1" cellspacing="1" border="1"> <table <meta content="text/html; charset=UTF-8" http-equiv="content-type" /> <thead><tr><td rowspan="1" colspan="3">CreateShowTest</td></tr></thead> <title>Test Suite</title> <tbody> </head> <tr> <body> <td>open</td> <table id="suiteTable" cellpadding="1" cellspacing="1" border="1" <td>/home/</td> <td></td> class="selenium"> </tr> <tbody> <tr> <tr><td><b>Test Suite</b></td></tr> <td>waitForElementPresent</td> <tr><td><a href="CreateShowTest">CreateShowTest</a></td></tr> <td>link=Crear nuevo evento</td> <tr><td><a href="DeleteShowTest">DeleteShowTest</a></td></tr> <td></td> </tbody> </tr> </table> <tr> </body> <td>clickAndWait</td> <td>link=Crear nuevo evento</td> </html> <td></td> </tr> </tbody></table></body> 7
    10. 10. LimitacionesPruebas limitadas a acciones de usuario.No soporta: - Condiciones - Iteración - Trazas y generación de informes - Etc... 8
    11. 11. Selenium RC.public class LoginTestCase extends SeleneseTestCase { public void setUp() throws Exception { setUp("http://localhost:8888/", "*firefox"); } public void testLoginTestCase() throws Exception { selenium.open("/home/"); verifyTrue(selenium.isElementPresent("logout-link")); selenium.click("logout-link"); selenium.waitForPageToLoad("30000"); verifyTrue(selenium.isElementPresent("login-link")); }} 9
    12. 12. Selenium RC.public class LoginTestCase extends SeleneseTestCase { Navegadores: public void setUp() throws Exception { setUp("http://localhost:8888/", "*firefox"); *chrome } *firefox *iexplore public void testLoginTestCase() throws Exception { selenium.open("/home/"); verifyTrue(selenium.isElementPresent("logout-link")); selenium.click("logout-link"); selenium.waitForPageToLoad("30000"); verifyTrue(selenium.isElementPresent("login-link")); }} 9
    13. 13. Selenium RC.public class LoginTestCase extends SeleneseTestCase { Navegadores: public void setUp() throws Exception { setUp("http://localhost:8888/", "*firefox"); *chrome } *firefox *iexplore public void testLoginTestCase() throws Exception { selenium.open("/home/"); verifyTrue(selenium.isElementPresent("logout-link")); selenium.click("logout-link"); selenium.waitForPageToLoad("30000"); verifyTrue(selenium.isElementPresent("login-link")); }} Selenium IDE permite generar el test Junit desde el script HTML 9
    14. 14. Arquitectura de Selenium RC 10
    15. 15. Selenium 2 y WebDriver 11
    16. 16. Selenium 2 y WebDriverSelenium: JavaScript dentro del navegador.WebDriver: componente específico - Firefox: JavaScript en un componente XPCOM. - IE: Uso del API de Automatización C++ - Chrome: Extensión con JavaScript V8 12
    17. 17. Para empezar Maven: pom.xml<project> [...] <dependencies> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium</artifactId> <version>2.0b2</version> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-server</artifactId> <version>2.0b2</version> </dependency> </dependencies> [...]</project> 13
    18. 18. DriverComponente que representa el navegador public class SimpleTest { private WebDriver driver = null; @Before public void create() { driver = new FirefoxDriver(); } } 14
    19. 19. Implementaciones 15
    20. 20. Implementacionesdriver = new HtmlUnitDriver(); 15
    21. 21. Implementacionesdriver = new HtmlUnitDriver(); driver = new FirefoxDriver(); 15
    22. 22. Implementaciones driver = new HtmlUnitDriver(); driver = new FirefoxDriver();driver = new InternetExplorerDriver(); 15
    23. 23. Implementaciones driver = new HtmlUnitDriver(); driver = new FirefoxDriver();driver = new InternetExplorerDriver(); driver = new ChromeDriver(); 15
    24. 24. Implementaciones driver = new HtmlUnitDriver(); driver = new FirefoxDriver();driver = new InternetExplorerDriver(); driver = new ChromeDriver(); 15
    25. 25. Page Object ModelLa forma de interactuar con WebDriver driver.get("http://localhost:8888/home"); 16
    26. 26. Page Object ModelLa forma de interactuar con WebDriver driver.get("http://localhost:8888/home"); 16
    27. 27. Page Object ModelLa forma de interactuar con WebDriver driver.get("http://localhost:8888/home"); - Localizar un elemento - Invocar una acción - Comprobar propiedades ‘visuales’ 16
    28. 28. Elementos de páginaWebElement header = driver.findElement({Locator});List<WebElement> shows = driver.findElements({Locator}); 17
    29. 29. Locator: Bypublic static By id(java.lang.String id)public static By linkText(java.lang.String linkText)public static By name(java.lang.String name) public Clase de métodos estáticos static By partialLinkText(java.lang.String linkText) con la estrategia de selección.publicstatic By tagName(java.lang.String name) public static By xpath(java.lang.String xpathExpression)public static By cssSelector(java.lang.String name) 18
    30. 30. WebElementComponentes devueltos por findElement()WebElement header = driver.findElement(By.cssSelector("#header"));List<WebElement> shows = driver.findElements(By.cssSelector("ul.data li")); 19
    31. 31. WebElementList<WebElement> shows = driver.findElements(By.cssSelector("ul.data li"));WebElement show = shows.get(0);show.findElement(By.cssSelector(".contents h3 a")).click(); 20
    32. 32. WebElementList<WebElement> shows = driver.findElements(By.cssSelector("ul.data li"));WebElement show = shows.get(0);show.findElement(By.cssSelector(".contents h3 a")).click(); <div class="grid_2 alpha"> <a title="Gervasio Sánchez. Desaparecidos" href="..."> <img src="..." class="thumbnail"> </a> <div class="small">{...}</div> </div> <div class="contents grid_4 omega"> <h3> <a href="..."> Gervasio Sánchez. Desaparecidos </a> </h3> <div class="author"> by <a href="...">test@example.com</a> hace 1 minuto</div> <div class="description">{...}</div> <a href="..." class="button toright">» Comprar ahora</a> </div> 20
    33. 33. WebElementList<WebElement> shows = driver.findElements(By.cssSelector("ul.data li"));WebElement show = shows.get(0);show.findElement(By.cssSelector(".contents h3 a")).click(); <div class="grid_2 alpha"> <a title="Gervasio Sánchez. Desaparecidos" href="..."> <img src="..." class="thumbnail"> </a> <div class="small">{...}</div> </div> <div class="contents grid_4 omega"> <h3> <a href="..."> Gervasio Sánchez. Desaparecidos </a> </h3> <div class="author"> by <a href="...">test@example.com</a> hace 1 minuto</div> <div class="description">{...}</div> <a href="..." class="button toright">» Comprar ahora</a> </div> 20
    34. 34. Accionespublic interface WebElement extends SearchContext { void click(); void submit(); void sendKeys(CharSequence... keysToSend); String getAttribute(String name); ... List<WebElement> findElements(By by); WebElement findElement(By by);} 21
    35. 35. RenderedWebElementConsultar propiedades visualesOperaciones de drag and drop.Simula el movimiento del ratón (hover)List<WebElement> shows = driver.findElements(By.cssSelector("ul.data li"));WebElement show = shows.get(0);Dimension size = ((RenderedWebElement) show).getSize() 22
    36. 36. RenderedWebElementConsultar propiedades visualesOperaciones de drag and drop.Simula el movimiento del ratón (hover)List<WebElement> shows = driver.findElements(By.cssSelector("ul.data li"));WebElement show = shows.get(0);Dimension size = ((RenderedWebElement) show).getSize() java.awt.Dimension[width=460,height=141] 22
    37. 37. Page Object Pattern 23
    38. 38. Page Object PatternCrea un objeto que encapsula la página con un API específico 24
    39. 39. PageObject Pattern• 25
    40. 40. PageObject Pattern public class KoliseoHomePage extends KoliseoPage { private WebElement showList;• public ShowThumbnail getShow(int pos) { } public KoliseoPage clickOnShow(int pos) { } public KoliseoPage buyTickets(int pos) { } } 25
    41. 41. PageObject Pattern public class KoliseoHomePage extends KoliseoPage { public class ShowThumbnail { private WebElement showList;• public ShowThumbnail getShow(int pos) { private final WebElement title; private final WebElement description; } private final WebElement buyButton; public KoliseoPage clickOnShow(int pos) { public String getTitle() { return title.getText(); } } public KoliseoPage buyTickets(int pos) { public void navigate() { title.click(); } } } public void buy() { buyButton.click(); } } 25
    42. 42. PageFactoryCrea un PageObject a partir de la página actual. driver.get(“http://localhost:8888/home”); KoliseoHomePage home = PageFactory.initElements(driver, KoliseoHomePage.class); 26
    43. 43. @FindBy@FindBy para configuración específica. - Por defecto utiliza el #id public class KoliseoHomePage extends KoliseoPage { @FindBy(css=".shows ul.data") private WebElement showList; @FindBy(css=".activities ul.data") private WebElement activities; public KoliseoHomePage(WebDriver driver) { super(driver); } } 27
    44. 44. @FindBy@FindBy para configuración específica. - Por defecto utiliza el #id public class KoliseoHomePage extends KoliseoPage { @FindBy(css=".shows ul.data") id private WebElement showList; name className @FindBy(css=".activities ul.data") css private WebElement activities; tagName linkText public KoliseoHomePage(WebDriver driver) { partialLinkText super(driver); xpath } } 27
    45. 45. KoliseoHomePagepublic class KoliseoHomePage extends KoliseoPage { @FindBy(css=".shows ul.data") private WebElement showList; public ShowThumbnail getShow(int pos) { List<WebElement> shows = showList.findElements(By.tagName("li")); WebElement show = shows.get(pos); return new ShowThumbnail(driver, show); } public KoliseoShowDetailPage clickOnShow(int pos) { ShowThumbnail show = this.getShow(pos); show.navigate(); return PageFactory.initElements(driver, KoliseoShowDetailPage.class); }} 28
    46. 46. @RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:springio-webdriver-test.xml")public class KoliseoHomeTest { @Autowired(required=false) private WebDriver driver = new HtmlUnitDriver(); private KoliseoHomePage home; @Before public void setUp() { driver.get(“http://localhost:8888/home); home = PageFactory.initElements(driver, KoliseoHomePage.class); } @After public void tearDown() { driver.quit(); } @Test public void showDetail() { assertTrue(home.hasShows()); String showTitle = home.getShow(1).getTitle(); KoliseoShowDetailPage showDetail = home.clickOnShow(1); assertEquals(showTitle, showDetail.getTitle()); } } 29
    47. 47. Show time! 30
    48. 48. ConclusionesSelenium IDE: Scripts HTMLSelenium RC: Código procedural en JavaSelenium 2 - WebDriver: Driver para el Browser - Código OO para nuestras páginas - Page Object Pattern: Nuestros APIs sobre WebDriver 31
    49. 49. Q&A 32

    ×