Test con Selenium Grid e JMeter
Molto spesso ci viene richiesto per le applicazioni web di effettuare test di carico o di verificare il comportamento con diversi browser. L’utilizzo congiunto di strumenti come Selenium e JMeter ci permette di avere un ambiente di test davvero utile e semplice da utilizzare.
Test d’integrazione con Selenium
Prima di mettere in piedi la nostra infrastruttura di test facciamo un piccolo riassunto per chi non conosce Selenium. Si tratta di un prodotto opensource, anzi di una suite di prodotti che permette di automatizzare i browser web. Attraverso diversi linguaggi (C#,Haskell,Java,JavaScript,Objective-,Perl,PHP,Python,R,Ruby) è possibile definire una serie di automazioni per il browser, in modo tale da testare e verificare il comportamento di un’applicazione web. Per scrivere questi test possiamo utilizzare SeleniumIDE, un ambiente di sviluppo per gli script Selenium.
E’ stato realizzato come estensione di Firefox e permette di registrare, modificare ed effettuare debug dei test. Una volta registrato, il test può essere esportato utilizzando diversi framework di test come JUnit,TestNG,NUnit,RSpec e unittest. Di seguito viene riportata la classe di test generata dalla navigazione effettuata su un’applicazione d’esempio
package com.javastaff.tests; import java.util.regex.Pattern; import java.util.concurrent.TimeUnit; import org.junit.*; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; import org.openqa.selenium.*; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.support.ui.Select; public class TestApplicazione extends TestCase{ private WebDriver driver; private String baseUrl; private boolean acceptNextAlert = true; private StringBuffer verificationErrors = new StringBuffer(); @Before public void setUp() throws Exception { driver = new FirefoxDriver(); baseUrl = "http://127.0.0.1:8080/"; driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); } @Test public void testLogin() throws Exception { driver.get(baseUrl + "/TestApp/"); driver.findElement(By.id("username")).click(); driver.findElement(By.id("username")).clear(); driver.findElement(By.id("username")).sendKeys("admin"); driver.findElement(By.id("password")).clear(); driver.findElement(By.id("password")).sendKeys("password"); driver.findElement(By.id("Login")).click(); try { String bodyText = driver.findElement(By.tagName("body")).getText(); Assert.assertTrue("Text not found!", bodyText.contains("BENVENUTO SU TESTAPP")); } catch (Error e) { verificationErrors.append(e.toString()); } } @After public void tearDown() throws Exception { driver.quit(); String verificationErrorString = verificationErrors.toString(); if (!"".equals(verificationErrorString)) { fail(verificationErrorString); } } private boolean isElementPresent(By by) { try { driver.findElement(by); return true; } catch (NoSuchElementException e) { return false; } } private boolean isAlertPresent() { try { driver.switchTo().alert(); return true; } catch (NoAlertPresentException e) { return false; } } private String closeAlertAndGetItsText() { try { Alert alert = driver.switchTo().alert(); String alertText = alert.getText(); if (acceptNextAlert) { alert.accept(); } else { alert.dismiss(); } return alertText; } finally { acceptNextAlert = true; } } }
In questo caso abbiamo registrato la fase di login e la verifica di una frase nella pagina dopo l’autenticazione. Inserendo le seguenti dipendenze Maven nel nostro progetto
<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.45.0</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency>
possiamo integrare questo test all’interno del processo di build Maven.
Configurare JUnit all’interno di JMeter
Ora che il nostro test Selenium utilizza JUnit è utile vedere come poter configurarlo all’interno di Apache JMeter. Questo è un prodotto opensource molto flessibile che permette di effettuare test e misurazioni relative. Prima di creare un piano di test con JMeter dobbiamo avere un jar che contiene tutte le nostre classi di test. Questo è possibile con Maven utilizzando il plugin maven-jar-plugin. Con la seguente configurazione andremo a creare in fase di build un jar con tutti i nostri casi di test.
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.6</version> <executions> <execution> <goals> <goal>test-jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Il jar generato avrà lo stesso nome del build con in più il suffisso -tests. Passiamo quindi alla configurazione di JMeter, che possiamo scaricare e unzippare tranquillamente. Come prima cosa dobbiamo inserire la libreria di Selenium all’interno della cartella $HOME_JMETER/lib. La libreria client Java in questione può essere scaricata direttamente dal sito di Selenium: http://www.seleniumhq.org/download/.
Ora rimane soltanto copiare il jar di test nella directory $HOME_JMETER/lib/junit ed avviare JMeter. Cliccando con il tasto destro sul test plan vuoto che si apre andiamo a selezionare Add->Threads(Users)->Thread Group. Ora su questo elemento aggiungiamo un JUnit Request (Add->Sampler->JUnit Request) configurato come riportato nella seguente immagine
In questo modo possiamo pilotare il nostro test da JMeter, settando parametri come il numero di Thread, il numero di richieste e visualizzando i tempi e le risposte che otteniamo.
Selenium Hub e Node
Effettuare dei test, specialmente di carico, da una singola macchina non è una cosa molto sensata. Per questo possiamo mettere in piedi un’infrastruttura dove le richieste provengano da diversi host, simulando appunto un traffico più simile a quello reale. Per fare ciò dobbiamo creare una Selenium Grid, una rete dove è presente un Hub e svariati Node che saranno poi i veri e propri host che effettueranno il test.
Scarichiamo quindi il file selenium-server-standalone-X.YZ.jar dal sito di Selenium e possiamo avviare il server nel seguente modo
java -jar selenium-server-standalone-X.YZ.jar -role hub
Ora su diversi altri sistemi possiamo avviare dei nodi con il seguente comando
java -jar selenium-server-standalone-X.YZ.jar -port 5000 -role node -hub http://IP_HUB:4440/grid/register -browser "browserName=internet explorer,platform=WINDOWS" -Dwebdriver.ie.driver="C:/IEDriverServer.exe"
Il comando appena eseguito lancia un nodo Selenium in ascolto sulla porta 5000, specifica dove si trova l’hub (porta di default 4440) e si registra come nodo con browser Internet Explorer. Dopo aver avviato diversi nodi possiamo vedere la situazione della nostra Selenium Grid andando all’indirizzo http://IP_HUB:4440/grid/console
Ora per agganciare il nostro caso di test alla Selenium Grid dobbiamo cambiare il setup del test nel seguente modo
@Before public void setUp() throws Exception { DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer(); capabilities.setCapability( InternetExplorerDriver. INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true); capabilities.setVersion("9.0"); driver = new RemoteWebDriver(new URL("http://IP_HUB:4440/wd/hub"), capabilities); baseUrl = "http://127.0.0.1:8080/"; driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); }
In questo modo, pilotando il tutto da JMeter, potremo pilotare i nostri test all’interno di un’infrastruttura come Selenium Grid, dove è possibile registrare dinamicamente nodi che possono avere differenti caratteristiche (uno solo con IE 9, uno solo con Chrome su piattaforma LINUX etc. etc.).

Looking for a right “about me”…
Commenti recenti