El patrón PageFactory se utiliza, junto con el patron Page Object a la hora de implementar pruebas funcionales para hacer el código más mantenible y evitar escribir código como:

WebElement searchInput = driver.findElement(By.xpath("//*[@id='twotabsearchtextbox']"));

De este modo, para hacer referencia a un elemento web, bastaría con importar:

import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

Utilizar FindBy para tomar los elementos, así;

@FindBy(xpath = "//*[@id='twotabsearchtextbox']")
private WebElement searchInput;

Inicializar esos elementos de la clase (u objeto de Page Object) con el PageFactory: (hay que pasar el driver y la propia clase)

public Search(WebDriver d2){
	driver = d2;  
	PageFactory.initElements(driver, this);
}

Y realizar operaciones sobre estos elementos en el método pertinente de la siguiente forma:

public void searchString(String product){
	driver.get("https://www.amazon.com");	
	searchInput.sendKeys(product); //p.e enviar un string a ese input
}

Para tenerlo bien claro dejo por aquí la estructura del proyecto y las clases necesarias. Por un lado estarán todas las clases u objetos (cada objeto del Page Object) y por otro las clases de los tests.

Selección_123

Clase “Buscador”:

package main;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.WebDriverWait;

public class Search{
	
	public static WebDriverWait wait;
	public static WebDriver driver;
	
	//webElements
	@FindBy(xpath = "//*[@id='twotabsearchtextbox']")
	private WebElement searchInput;
	
	@FindBy(xpath = "//*[@id='nav-search']/form/div[2]/div/input")
	private WebElement searchButton;
    
    	public Search(WebDriver d2){
		driver = d2;  
		PageFactory.initElements(driver, this);
	}
    
	public void searchString(String product){
		driver.get("https://www.amazon.com");	
		searchInput.sendKeys(product);
		searchButton.click();
	}
}

Clase que contiene el test:

package testsPaths;

import java.util.Arrays;

import main.Search;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;


public class TestExample {

	private static WebDriver driver;
	private static Search searchPage;
	
	private String product1 = "flowers"; 
	private String product2 = "mushrooms";
	
	@BeforeClass
	public static void setUp(){	
		System.setProperty("webdriver.chrome.driver", "src/chromedriver"); 	
		ChromeOptions options = new ChromeOptions();
		options.setExperimentalOption("excludeSwitches", Arrays.asList("ignore-certificate-errors"));
		driver = new ChromeDriver(options);  
		searchPage = new Search(driver); //inicializamos nuestro page object "buscador"
	}
		
	@AfterClass
	public static void tearDown(){
		driver.quit();
	}

	@Test
	public void testMethod() throws InterruptedException{
		searchPage.searchString(product1);
		searchPage.searchString(product2);
	}
}

¡Sed buenos!

El patrón Page Object se ha puesto muy de moda en el mundo de las pruebas funcionales debido a que nos ayuda a tener un código más limpio, una mejor estructura de proyecto y en definitiva un código más mantenible.

Se basa sencillamente en separar toda la implementación de la aplicación de lo que es su funcionamiento. De esta forma nos centramos en probar nuestra web página a página, como si un usuario navegara a través de ella y teniendo en cuenta que cada página para nosotros será un objeto. Así sólo nos quedará interactuar con cada uno de ellos y devolver un objeto (página) inmediatamente posterior para poder encadenar caminos funcionales.

Para tener una imagen clara de esto, imaginemos una aplicación con distintas páginas o elementos como la siguiente:

  1. Vista de la página de Registro
  2. Vista de la página de Login
  3. Página de Gestión de usuarios
  4. Página de Gestión de notas
  5. Logout (en la misma vista que las páginas de gestión)

pageobject

Y en cada página tendremos agrupado todo el comportamiento de la misma, es decir, ¿qué se puede hacer en cada página?

  • para 1 tendremos todas las acciones que se pueden llevar a cabo en un registro (rellenar formunario ok, rellenar formulario de forma incorrecta, marcar check, aceptar)
  • para 2 tendremos todas las acciones para realizar un login (rellenar formulario ok, rellenar formulario de forma incorrecta, aceptar)
  • para 3 idem (rellenar campos, buscar y añadir nuevo usuario)

así sucesivamente…

Teniendo esto, se pueden crear tests de cada página, por ejemplo:

  • para 1
    • registro ok (que implica rellenar ok el formulario + marcar check + aceptar)
    • registro no_ok (por ejemplo rellenar ok + no marcar check + aceptar)
  • para 2
    • login ok (rellenar formulario ok + aceptar)
  • para 3
    • buscar usuario (rellenar campos + buscar)

De este modo, cada página permite que sus métodos enlacen con los métodos de otras páginas. Y bien, sólo quedaría unir estos métodos entre ellos para formar caminos funcionales así:

registro ok > login ok > buscar usuario > cerrar sesión

Este patrón está muy relacionado con otro llamado PageFactory a nivel de código. En un nuevo post explicaré este otro ;)

¡Saludos!

Hello!!

Quería contar qué herramientas utilizo en linux para hacer tanto capturas como vídeos de los bugs detectados en webs.

Si hay algo que me da rabia es no poder explicar con claridad un bug descubierto. No me gusta poner al “devy” (así llamo cariñosamente a mis compañeros desarrolladores) en la tesitura de no saber cómo he sido capaz de obtenerlo.

Para ello, utilizar capturas de pantalla y grabaciones de los pasos seguidos son de gran ayuda.

##Para capturas de pantalla

  • Utilizo Shutter. Es genial porque la captura realizada se puede editar en el momento para marcar exactamente donde se encuentra el bug (con un cuadro, subrayado, flecha, texto…) Se instala con un simple:
1
$ apt-get install shutter

##Para grabaciones

  • Utilizo SimpleScreenRecorder. Permite directamente exportar el video en .mp4 y que no ocupe una barbaridad. He utilizado otros programas donde aún cambiando las características del video a exportar, éste era muy pesado o el formato elegido no era el adecuado para que todos los sistemas pudieran reproducirlo correctamente.

Los recomiendo encarecidamente :)

¡Espero que os sea útil!

El otro día me topé con una forma de testear web un tanto curiosa.

Parece ser que existe un personajillo :) llamado Richard que ofrece sus servicios como tester web mientras bebe cerveza (espero, querido lector, que no te estés viendo reflejado en esto ahora mismo…) pero no sólo eso, ¡lo hace borracho!

Por lo que he leído, sostiene que el diseño y la funcionalidad de una web deben ser muy sencillos, tanto que la web pueda ser utilizada por un usuario borracho sin problemas.

En su página tiene enlaces a los videos donde se graba haciendo estos tests, por si queréis echar un ojo :D

Amigos, espero que no se os vaya de las manos ^.^