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
5. Componentes
Selenium Core
- Motor de ejecución empotrado en el Navegador
Selenium IDE
- Herramienta para grabar los tests en HTML
Selenium RC (Remote Control)
- Tests escritos en Java, Ruby, Python, Perl, PHP...
5
6. Selenium IDE
FireFox plugin que graba
y ejecuta los tests.
6
10. Limitaciones
Pruebas limitadas a acciones de usuario.
No soporta:
- Condiciones
- Iteración
- Trazas y generación de informes
- Etc...
8
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. 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. 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
16. Selenium 2 y WebDriver
Selenium: 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
18. Driver
Componente que representa el navegador
public class SimpleTest {
private WebDriver driver = null;
@Before
public void create() {
driver = new FirefoxDriver();
}
}
14
22. Implementaciones
driver = new HtmlUnitDriver(); driver = new FirefoxDriver();
driver = new InternetExplorerDriver();
15
23. Implementaciones
driver = new HtmlUnitDriver(); driver = new FirefoxDriver();
driver = new InternetExplorerDriver(); driver = new ChromeDriver();
15
24. Implementaciones
driver = new HtmlUnitDriver(); driver = new FirefoxDriver();
driver = new InternetExplorerDriver(); driver = new ChromeDriver();
15
25. Page Object Model
La forma de interactuar con WebDriver
driver.get("http://localhost:8888/home");
16
26. Page Object Model
La forma de interactuar con WebDriver
driver.get("http://localhost:8888/home");
16
27. Page Object Model
La forma de interactuar con WebDriver
driver.get("http://localhost:8888/home");
- Localizar un
elemento
- Invocar una acción
- Comprobar
propiedades ‘visuales’
16
28. Elementos de página
WebElement header = driver.findElement({Locator});
List<WebElement> shows = driver.findElements({Locator});
17
29. Locator: By
public 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
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. 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. PageFactory
Crea un PageObject a partir de la página actual.
driver.get(“http://localhost:8888/home”);
KoliseoHomePage home = PageFactory.initElements(driver, KoliseoHomePage.class);
26
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. @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. KoliseoHomePage
public 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. @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
Pruebas Unitarias.\n Componentes aislados del entorno\n Dependencias (Dobles de prueba)\n Framework.\n Pruebas de Integraci&#xF3;n\n Componentes trabajando en colaboraci&#xF3;n\n Infraestructura simplificada (BD, Sistemas externos...)\n Pruebas end-to-end\n La aplicaci&#xF3;n completa. Desde la visi&#xF3;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&#xE1;gina\n Implementan sus operaciones\n
Representan fragmentos de la p&#xE1;gina\n Implementan sus operaciones\n
Representan fragmentos de la p&#xE1;gina\n Implementan sus operaciones\n
Representan fragmentos de la p&#xE1;gina\n Implementan sus operaciones\n
Representan fragmentos de la p&#xE1;gina\n Implementan sus operaciones\n
Representan fragmentos de la p&#xE1;gina\n Implementan sus operaciones\n
Drag &#x2018;n&#x2019; drop y hover es mejor a trav&#xE9;s del\nAdvanced User Interactions API\n\n&#xA0;ActionChainsGenerator builder = ((HasInputDevices) driver).actionsBuilder();\n&#xA0; &#xA0;builder.keyDown(Keys.CONTROL)\n&#xA0; &#xA0; &#xA0; &#xA0;.click(someElement)\n&#xA0; &#xA0; &#xA0; &#xA0;.click(someOtherElement)\n .clickAndHold(someElement)\n&#xA0; &#xA0; &#xA0; &#xA0;.keyUp(Keys.CONTROL);\n builder.build();\n builder.permform();\n\n\n\n
Aqu&#xED; 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&#xE1;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&#xED;a hacer Asserts\n
Los componentes encapsulan la carga en el m&#xE9;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&#xED;a\n
La p&#xE1;gina protegida\n Carga el Login (si ya se ha hecho login no se rehace)\n