74
1 Outils de Tests d'Interface a) Plateformes de tests : JUnit, PHPUnit, Qunit b) Outils de qualité : sonar c) Selenium d) Outils de déploiement : maven http://www.fil.univ-lille1.fr/~bilasco/OTI/OTI2014a.pdf

Outils de Tests d'Interface - fil.univ-lille1.frbilasco/OTI/OTI2014a.pdf · Interface & Interactions Code T. Interface T. Métier T. Métier. 5 ... Test unitaires – Exos 1

  • Upload
    doanh

  • View
    216

  • Download
    0

Embed Size (px)

Citation preview

1

Outils de Tests d'Interface

a) Plateformes de tests : JUnit, PHPUnit, Qunit

b) Outils de qualité : sonar

c) Selenium

d) Outils de déploiement : maven

http://www.fil.univ-lille1.fr/~bilasco/OTI/OTI2014a.pdf

2

Tests

● Les tests assurent

– qualité du code : fiable, robuste

– tests de régression fréquents

– retour d'expérience rapide

– identification des problèmes rares et/ou non testé manuellement

– documentation : exemples fonctionnels

● A quel prix ? Quand est-ce qu'on en écrit ?

● Séparation entre code tests et code métier

– code défi ni, développé et livré séparément des tests● src/ vs test/

3

Tests

Dans un cadre collaboratif code écrit 1 fois, répliqué n fois

Dans un cadre Agile itérations courtes, documentées par les tests

eXtreme Programming (XP) / Test Driven Development développer les tests unitaires en même temps/avant le

programme à tester à partir des spécifi cations on n'écrit que le code nécessaire à valider les tests

… en TP ?

4

Tests

Qu'est-ce … et comment écrire des Tests unitaires ?http://fr.wikipedia.org/wiki/Test_%28informatique%29http://fr.wikipedia.org/wiki/Test_unitairehttp://portail.fi l.univ-lille1.fr/portail/index.php?dipl=MInfo&sem=S8&ue=SVL

Tests pour les applications connectées

Code métier

BD

Interface & Interactions

Code

T. Interface

T. Métier T. Métier

5

● Outils pour tests unitaires : – JUnit 4.0– PHPUnit, SimpleTest– QUnit JS, Jasmine, Buster.JS, jstestdriver ...

● Outils pour tests interface utilisateur : – Selenium

● Exercices (rendus à la fi n de séances / module)● Evaluations

– Couverture de tests pour l'application WebA

6

Organisation générique des tests

Code

- classes- méthodes

Ou

- modules- fonctions/procédures

Test Case A

- tests - par fonctionnalités

- par méthode/fonction- par contexte d'usage

AssertionsEchecs

Test Case B

- tests - par fonctionnalités

- par méthode/fonction- par contexte d'usage

AssertionsEchecs

Test suite

7

Un Cas de Test - Principe général

● Hypothèse

– configuration de l'état de départ du système● Actions (testées)

– transformation sur l'état du système● Résultat attendu

– vérification de l'état attendu (assert)

– production d'une exception

8

Tests – JUnitorg.junit.* (JUnit 4.0)

Interface : Test

Classes : (J4.0) Toute classe contenant @org.junit.Test

(J4.0) @org.junit.runners.Suite

Assert (méthodes assertXXX() et failZZZ()) - JSONAssert de net.sf.json.tests → asserts pour JSONObject, JSONArray

Méthodes

@Test or @Test(expected=Exc.class) void yyy() {...} (Test.)assertXXX(...) - True, False, Equal @Before{Class} – init. des objets auxiliaires par test/classe

@After{Class} - relâche les objets auxiliaires @Suite.SuiteClasses({ MyT.class })

9

Exemple JUnit 4.x - Assert

import org.junit.*;

public class MoneyTest { //Construire un nouveau test case

private Money f12EUR, f14EUR;

@BeforeClass /* or Before – each Test */

protected void init() { //Construction de objets tests

f12EUR = new Money(12,"EUR");

f14EUR = new Money(14,"EUR");

}

@Test

public void simpleAdd () { //Une des méthodes de test

Money expected = new Money(26,"EUR");

Money result= f12EUR.add(f14EUR);

assertTrue(expected.equals(result));

}

} .

10

Exemple JUnit 4.x - Exception

import org.junit.*;

public class MoneyTest { //Construire un nouveau test case

private Money f12EUR, f14EUR;

@BeforeClass /* or Before – each Test */

protected void init() { //Construction de objets tests

f12EUR = new Money(12,"EUR");

f14EUR = new Money(14,"EUR");

}

@Test(expected=SubImpossibleException.class,timeout=msTimeoutValue)

public void simpleSubImpossible () { //Une des méthodes de test

Money result= f12EUR.add(f14EUR);

}

} .

11

Suites de tests - JUnit

Organiser/Composer/Regrouper plusieurs Tests JU 3.8 : TestSuite TestSuite suite = new TestSuite("MoneyTestSuite"); suite.addTestSuite(MoneyTest.class); //ajout de tous les tests suite.addTest(new AnotherMoneyTest("testOtherMoneyMethodName");

//ajout de tests spécifi ques JU 4.0 : Suite @RunWith(Suite.class) @SuiteClasses({MoneyTest.class,AnotherMoneyTest.class})

class AllTests {} ;;

RepeatedTest (JU3.8) Performance ou erreur intermittente suite.addTest(new RepeatedTest(new MoneyTest("testSimpleAdd"),100)); suite.addTest(new RepeatedTest(new MoneyTest("testComplexAdd"),100));

12

JUnit Exercices

● http://forge.fil.univ-lille1.fr/OTI/wiki/JUnitExo

● http://forge.fil.univ-lille1.fr/OTI/wiki/JUnit4Exo

MoneyFactory.class

::+getDefaultFactory+createMoney

Money.class

- Money+getValue +getCurrency

+toString

MoneyOps.class

:: +simpleAdd

IncompatibleCurrenciesException.class

UnexistingCurrencyException.class

MoneyAddTestCase.class

+testSimpleAdd

MoneySameCurrTest.class

+testSame+testNotSame

MoneyEqTest.class

+testMemeValeurMemeDevise+testMemeValeurDeviseDifff//

13

Outils de Tests d'Interface

a) Plateformes de tests : JUnit, PHPUnit, Qunit

b) Outils de qualité : sonar

c) Selenium

d) Outils de déploiement : maven

http://www.fil.univ-lille1.fr/~bilasco/OTI/OTI2014a.pdf

14

Tests Unitaires pour Javascript

● Une grande variété de plateformes de tests JS– http://en.wikipedia.org/w/index.php?title=List_of_unit_testing_frameworks&section=32#JavaScript

● Restructurer votre code en vue de mettre en place de tests

– Séparer la partie fonctionnelle/métier ...

– … de la partie rendu (modification DOM, alertes, etc.)

– Organisez-le en fonctions indépendamment testables

– Un exemple de restructuration : http://qunitjs.com/intro/

15

Tests Unitaires pour Javascript

● Réfléchir à la séparation entre tests clients et tests serveurs

– Tests unitaire JS (client) vs Tests unitaires Java/PHPUnit (serveur)

Code métier

BD

Interface & Interactions

Code

T. Interface

T. Métier T. Métier

16

QUnit by JQueryhttp://code.jquery.com/qunit/qunit-1.12.0.csshttp://code.jquery.com/qunit/qunit-1.12.0.js

● Tests et reports matérialisés dans des pages HTML

● TestCases

– Synchrones : test (nom[, nbr_tests], funcDef)

– Asynchronnes : asyncTest(nom, [nbr_tests,] funcDef)

● stop() puis setTimeout() sur appel bloquant puis start()

– Structurées: module(nomMod, setup : funcDef, tearDown : funcDef)

● module("suiteA", setup:function(){...}, teardown:function(){…})● asyncTest("testA1", function() {...})● test("testA2",3,function() {...}) ← ici sont attendues 3 assertions

● TestSuites (qunit-composite.js sur github.com)

– QUnit.testSuites(["moduleA.html", "moduleB.html"]);

17

QUnit – test & throwsexemples

test("test accesseurs", 2, function(){

var m=new money(1,"EUR");ok(m.getValue()==1,"valeur = 1");equal(m.getCurrency(),"EUR","currency = EUR");

});

test("test simple ops", 2, function(){ var m1=new money(1,"EUR"); var m2=new money(2,"EUR"); var m3=new money(3,"EUR"); ok(m3.equals(MoneyOps.add(m1,m2)),"3e = 1e+2e");});

test("test multi devise add", 1, function(){

var m1=new money(1,"EUR"); var m2=new money(2,"CHF"); throws(function() {var m3=MoneyOps.add(m1,m2)},

DevisesIncompatibleExc, "Devises Incompatibles");});

18

QUnit – tests and Ajax … the wrong way

module("async");

test("start",function(){ ok(true); });

test("connect using Ajax",function(){ var xmlhttp=new XMLHttpRequest(); xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { equal(xmlhttp.responseText,10); console.log("recieved "+xmlhttp.responseText); } } xmlhttp.open("GET","random.php",true); xmlhttp.send();});

test("end",function( ){ ok(true); });

<?phpsleep ( rand ( 2, 4));echo rand (9,11);?> random.php

http://www.fil.univ-lille1.fr/~bilasco/OTI/random_test_NS.htmlhttp://www.fil.univ-lille1.fr/~bilasco/OTI/random_test_NS.js

19

QUnit – tests and Ajax

module("async");

test("start",function(){ ok(true); });

test("connect using Ajax",function(){ var xmlhttp=new XMLHttpRequest(); xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { equal(xmlhttp.responseText,10); console.log("recieved "+xmlhttp.responseText);

QUnit.start(); } } xmlhttp.open("GET","random.php",true); xmlhttp.send(); QUnit.stop() ;});

test("end",function( ){ ok(true); });

<?phpsleep ( rand ( 2, 4));echo rand (9,11);?> random.php

http://www.fil.univ-lille1.fr/~bilasco/OTI/random_test_NS2.htmlhttp://www.fil.univ-lille1.fr/~bilasco/OTI/random_test_NS2.js

20

QUnit – asynchronous tests et Ajax

module("async");

test("start",function(){ ok(true); });

asyncTest("connect using Ajax",function(){ //implicit QUnit.stop() var xmlhttp=new XMLHttpRequest(); xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { equal(xmlhttp.responseText,10); console.log("recieved "+xmlhttp.responseText); QUnit.start(); } } xmlhttp.open("GET","random.php",true); xmlhttp.send();});

test("end",function( ){ ok(true); });

<?phpsleep ( rand ( 2, 4));echo rand (9,11);?> random.php

http://www.fil.univ-lille1.fr/~bilasco/OTI/random_test.htmlhttp://www.fil.univ-lille1.fr/~bilasco/OTI/random_test.js

21

QUnit by JQueryhttp://code.jquery.com/qunit/qunit-1.12.0.csshttp://code.jquery.com/qunit/qunit-1.12.0.js

● Assertions

– ok(param[,msg]) – test passé si paramètre param true

● ok (1==1,"1 est tjs égal à 1") ;

– [strict|deep}equal(result,expected[,msg]) – test passé si paramètres {strictement (type et valeur) / structurellement } égaux

● strictEqual(1=="1","jamais ça marchera") ;● equal(1=="1","la rigueur c'est pas pour nous") ;

– throws(funcDef,expected[,msg]) – test passé si expected lancée

● throws(function(){throw "oups"},"oups","oups c'est passé")

22

QUnit by Jquery

● Page HTML de test QUnit

– inclusion de scripts src

– inclusion de scripts tests

● Résultats et données dans des divs prédéfinies

– id='qunit' – affichage des résultats

– id='qunit-fixture' – inclusion des éléments (champs, etc.) servant de support pour la réalisation des tests

● Utilise le trigger de jQuery pour simuler les interactions– .trigger( eventType [, extraParameters] )

23

Qunit - exemplequnit.js + qunit.css

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.12.0.css" /><script src="http://code.jquery.com/qunit/qunit-1.12.0.js"></script><script src="../src/money.js"></script><script src="../test/money_test.js"></script></head><body><div id="qunit"/><div id="qunit-fixture"/></body></html>

module("money", {// setup:function(){alert("setup money");},// teardown:function(){alert("teardown money");}});

test("test accesseurs", 2, function(){

var m=new money(1,"EUR");ok(m.getValue()==1,"valeur = 1");equal(m.getCurrency(),"EUR","currency = EUR");

});

24

Test unitaires – Exos 1

● QUnit

● Commencer à réfléchir à comment mettre en place les tests sur votre projet WebA

money.js

money(v,curr)getValue

getCurrrencyequals

money_ops.js

money(v,curr)getValue

getCurrrencyequals

money_exc.js

DevisesIncompatibleExc

money_test.js

constructoraccesseurs

equals

money_test.html

money_ops_test.js

simpleAddmultiDevise

money_ops_test.html

money_test_suite.js

money_test.htmlmoney_ops_test.html

money_test_suite.html

25

Retours

● « // throw new Exception » (this.d1 + " " + this.d2)

● « Le test c'est bien mais la console c'est mieux »– try { ... } catch (e) {console.log(e.toString());}

● «Ca y est, un test ca suffit »– var f=new factory(); ok(f.cur.length==2,"nb = 2"); equal(f.cur[0],"EUR","");

– var m1=f.create(1,"E") ; var m2=f.create(2,"E") ; equal(f.crees["E"]=3);

● «Un test en plus ne fait pas de mal »MoneyFactory.prototype.create = function (value, currency) { if (this.currencies.indexOf(currency.toUpperCase()) == -1) throw new Exc(); return new money( value, currency );}test("test create", function(){ throws(function() {var m = this.fact.create(1, "YEN")}, .., "Devise Inexistante"); throws(function() {var m = this.fact.create(-1, "EUR")}, ...,"Monnaie Négative");});

26

● « Je me fâche avec personne »– ok(m1.getValue()<"0","Negatif") ;

– If (v<0) alert 'Attention' ;

– default : this.moneyClass = mFactory.Euro;

● « Je suis généreux»– m1 = new Money(1, "EUR") ; m1.setValue(100) ;

● « Tant que j'utilise pas mes sous c'est pas grave »– this.curr=curr ; et puis test sur currency en Money_Ops

● « Egocentric »– throw new MonPropreEx

27

QUnit

● Tests sur le comportement métier des scripts

● Tests sur le comportement de l'interface

– changements dans le DOM

– apparition des alertes

28

QUnit et DOM

● Les tests s'exécutent au sein d'une page ← contexte DOM

● Isoler le contexte DOM associé dans le div id=qunit-fixtures

● Avant chaque tests construire les fixtures

– réfletant l'état du DOM suite aux actions de l'utilisateur var fixture=""; fixture+=("<div id='res'></div>"); fixture+=("<form id='form0'>"); fixture+=("<input type='text' id='v1' name='v1' value='2'/>"); fixture+=("<input type='text' id='c1' name='c1' value='EU'/>"); … var fixtureNode=document.getElementById("qunit-fixture"); fixtureNode.innerHTML=fixture; … c.computeResult(document.getElementById('form0'));

equal(c.message,"...") ;

29

QUnit et (window.)alert

● Pas d'assertion spécifique pour traiter les alertes

● Redéfinir la fonction window.alert

● Garder une trace dans le div qunit-fixtures

...

30

Test unitaires – Exos 2

● QUnit et fixtures

index.html

div resform

calc.js

calc()computeResult(form)

displayResult(div)

calc_test.js

test computeResulttest outputResult

Utilisation de fixtures

var fixture="" ;fixture+="<div id='res'>.." ;fixture+="<form..>" ;fixture+="<input ..>" ;…document.getElementById

("qunit-fixture").innerHTML=fixture

31

Outils de Tests d'Interface

a) Plateformes de tests : JUnit, PHPUnit, Qunit

b) Outils de qualité : sonar

c) Selenium

d) Outils de déploiement : maven

http://www.fil.univ-lille1.fr/~bilasco/OTI/OTI2014a.pdf

32

SONAR

● Outil pour mesurer la qualité du code

33

SONAR

● Analyser le code (sonar-runner)

– Structure

– Convention de Codage

– Couverture et Tests

● Archivage des informations (sonarQube)

– Rapports

– Evolution de la qualité

● Solution générique

– plugins par langage et par fonctionnalité

SonarQube

R1 R2

sonar runner

plugins

outils externes

34

Sonar et JS

● Plugin SonarQube Javascript disponible

– n'extrait pas directement les données de couverture de tests

● Exécuter les tests JS en ligne de commande + récupérer résultats

– utiliser JsTestDriver (1.3.5) – un autre framework de tests JS

– serveur prenant la main sur un ou plusieurs navigateurs

– QUnitAdapter – fonctionnalités minimales (test, ok)

– configuration du projet (jsTestDrive.conf)

● Récupération des informations de « coverage » (1.3.5)

● Alimenter SonarQube en utilisant sonar-runner

35

JsTestDriver et QunitAdapter

● QUnit.test → QUnitTestCase extends (Js)TestCase

● ok -> assertTrue

● + equal

● + throws

● + fixtures

36

Sonar - exercices

● Travail sur le projet Money_JS

– Installer SonarQube

– Configurer sonar-project.properties (runner->qube)

– Lancer Analyse

– Installer JsTestDriver

– Configurer jsTestDriver.conf

– Lancer Analyser / Récupérer informations sur les tests

– Faire évoluer votre code

– Re-lancer l'analyser

37

Sonar - exercices

● Travail sur le projet Money_Java

– Installer SonarQube

– Configurer sonar-project.properties (runner->qube)

– Lancer Analyse

– Configurer Maven

– Lancer Analyser / Récupérer informations sur les tests

– Faire évoluer votre code

– Re-lancer l'analyseur

38

Selenium – Tests UIhttp://seleniumhq.org/docs/

● Selenium automates browsers.

● Initialement conçu pour réaliser des tests dans les applis Web

– Interaction à travers les pages d'un navigateur

– Clique/Ecrit/Valide/Interagit/Constate à ma place● Construire des macros visuels pour la maintenance

● Formalisme pour décrire les actions simulées

● Formalisme pour constater/mésuser les effets des actions

– sur la page (modifications du DOM)

– ou dans l'interaction (alertes ...)

39

Selenium – une famille de solutions

● Selenium IDE

– Plugin navigateur pour enregistrer/exécuter les scénarios de tests

– Création des tests rapides

– Reproduire des bugs

– Absence de logs, metrics

● Selenium WebDriver

– Tests robustes en vue d'automatiser l'étude de la régression

– Passage à l’échelle des tests

– Clients en Java, C#, Python, Ruby, PHP, Javascript

40

Selenium IDE Commandes (ou Selenese)

● Enregistrer des Actions

– Ouvrir une page (open)

– Saisir un texte (type)

– Cliquer (click*)

– Choisir options (select*)

● Accessors pour le contenu

● Assertions des effets sur

– le contenu du document

– les propriétés des éléments

– les fenêtres du navigateur

● 1 Script = actions + assertions

41

Selenium IDE – Commandes et suites

● Une commande selenese est composée de :

– Action : ensemble prédéfini des types de commandes

– Locator : comment identifier/référencer l'élément concerné

● id, xpath, css

– Value : paramètre de la commande

● Un encodage HTML pour l'instant

● Assembler les commandes dans un test case (.html)

– <table> dont les lignes sont des commandes

– <tr> commande et <td> éléments de la commande● Assembler les tests cases en tests suite

– <table> dont les lignes sont des liens vers tests cases

42

Selenium UI – Référencement des élémentsLocators

● Référencer les éléments concernées par les actions

● Par id: id = elementID (attribut id requis sur les éléments à référencer)● Par name: name = elementNom (attribut name requis)● Par identifier: identifier=formNOMouID (par id et puis par name)● Par XPath: xpath=/html/body/form0/input[3], xpath=//form/input[@id='x']● Par link: link=Texte_Entre_<A>_et_</A>● Par DOM: dom=document.getElementById('myForm')● Par CSS: css=#loginForm input[type="button"] (4)

● Adaptez vous à la nature du document testé

● Choisissez des références robustes aux changements dans la page – limitez les contraintes de localisation dans le code

43

Selenium UI – Actionshttp://release.seleniumhq.org/selenium-core/1.0/reference.html#actions

● Interactions

– Souris : {double/}click{/At}, mouseMove{/At}, dragAndDrop{/ToObject} ...

– Clavier : keyPressed,{alt/control}Key{Up/Down}, type …

● Formulaires : select(selectLocator,labelLocator)

● Fenêtres et PopUp

– Ouverture: openWindow, select{Window,Frame,PopUp}

– Interaction: choose{Cancel/OK}OnNextConfirmation, deselectPopUp

● Scripts : addScripts

● Interactions+temps d'arrêt pour rechargement : XXXAndWait

– À éviter en présence d'AJAX

<tr><td>clickAndWait</td><td>id=nextPageBtn</td><td></td></tr>

44

Selenium UI - Actions

● Stockage et Variables

– storeXXX{/Present/NotPresent}, storeEval

<tr><td>storeText</td><td>id=login</td><td>lg</td></tr>

<tr><td>storeEval</td><td>storedVars['lg'].toUpperCase()</td><td>M</td></tr>

● Validation

– assertXXX{/Present/NotPresent} → le test s'arrête définitivement

– verifyXXX → test continue, notification de l'échec

– waitForXXX → le script attend qu'un état soit observé (support AJAX)

45

Selenium UI - Exemple

Addition Test

open ~bilasco/MoneyMoneyMoney/index.php

type name=v1 12

type name=c1 EUR

type name=v2 12

type name=c2 EUR

clickAndWait css=input[type="submit"]

assertText id=ops ADD

assertText id=result_detail (EUR) 24

v1

v2

d1

d2

ops

result_detail

46

Selenium WebDriver

● Construire de tests d'intégration automatisé à base d'API

– s'abstraire d'un navigateur spécifique

– automatiser exécution

– structures de contrôle

● Navigateur supportés

– Safari, InternetExplorer, Firefox, Opera, Chrome

● Dispositifs d'accès

– Desktop, Android, Iphone

● API décliné en

– java, c#, python, ruby, php, perl, javascript

47

Selenium TestsAPI.java

SeleniumWeb Driver

server

Android Chrome Firefox

Actions Créer WebDriverExécuter Selenesse

InformerSignaler

Selenium TestsAPI.php

Selenium TestsAPI.js

RemoteWebDrivers

48

Selenium WebDriver – APIorg.openqa.selenium.*

● Navigateur générique : RemoteWebDriver

● Navigateur spécifique : selenium.{nomnavigateur}

– classes spécifiques pour interaction avec navigateur spécifique

● Interactions simples et complexes : selenium.interactions

– ClickAction,ClickAndHold,ContextClick,DoubleClick,...

– KeyDownAction,KeyUpAction,SendKeys

– touch.*

– CompositeAction

● Localisation des élements : Interface Locators

– selenium.internals

● FindsBy{ClassName,CssSelector,Id,LinkText,Name,TagName,XPath}

49

Selenium Web Driver - RemoteWebDriver

● Capabilities – un sac de CapabilityType

– startSession(Capabilities)/stopSession() ● Chargement page : get(String adresseWeb)

● Naviguer navigate()

– back(),forward(),refresh(),to()

– switchTo().{alert(),frame(name),window(name)}● Executer scripts

– execute{Async}Script(String script, Object... args)

● Contrôle de la souris/clavier getKeyboard()/getMouse()

50

Selenium Web Driver - RemoteWebDriver

● Localiser : findElement(s){ByClassName,...}(Object cle)

– les WebElement sont contrôlables

– By.xpath, By.id, By.tagName, By.name …

51

Selenium Web Driver - {Remote}WebElement

● Etat du WebElement

– isEnabled(),isSelected(),isDisplayed()

– getSize(),getLocation(),getText(),getAttribute()

– findElement()

● Interactions simples à partir du WebElement

– welt.sendKeys(), welt.click(), welt.submit()

● Interactions complexes avec interactions.Actions

– construire une suite d'actions new Actions(driver)

– ajouter this.keyDown(Keys.CONTROL).click(welt1).keyUp(welt2).

– executer this.build().perfom()

● Interagir avec les options d'un select dans un formulaire : Select(WebElement)

52

Selenium WebDriveTemps d'arrêt (...AndWait)

● Navigation entre pages / Rechargement de pages / AJAX

● Combien de temps attendre avant de poursuivre?

● Observer un changement

– Apparition/Disparition d'un élément sur la page

– Changement d'état sur un élément existant

– Alertes

53

Selenium WebDriveTemps d'arrêt (...AndWait)

● Objets marquant les temps d'arrêt : WebDriveWait

WebDriverWait wdwait = new WebDriverWait(driver, timeout);

● Continuer à condition que …

wdwait.until(ExpectedCondition)

● Collections de conditions prédéfinies ExpectedConditions

– [in]visibilityOf(WebElt.)/[in]visibilityofElementLocated(By l) ...

wdwait.until(ExpectedConditions.alertsPresent());

wdwait.until(ExpectedConditions.presenceOfElementLocated(By.id("v1")))

● Definir ses propres ExpectedCondition

– surcharger la methode apply(WebDriver d)

54

Selenium WebDriveTemps d'arrêt (...AndWait) - Exemple

● Utilisation d'une condition prédéfinie

● Création d'une condition

new WebDriverWait(driver,10,500). until(ExpectedConditions.

visibilityOfElementLocated(By.id("result"))

;

new WebDriverWait(driver,10,500). until(new ExpectedCondition<Boolean>() {

public Boolean apply(WebDriver d) {return d.findElement(By.id("result")).isDisplayed() ;

} }

55

Selenium UI - Exemplev1

v2

c1

c2

ops

result_detail

@Before public void createDriver() {driver = new FirefoxDriver();}@Test public void test() { driver.get("http://localhost/~bilasco/Money/index.php"); WebElement element = driver.findElement(By.name("v1"));

element.sendKeys("12"); … ;element.submit(); new WebDriverWait(driver, 10).until(ExpectedConditions.

visibilityOfLocatedElement(By.id("result_detail"))); assertEquals(driver.findElement(By.id("result_detail")).getText(),

"(EUR) 24")) ; }@After public void releaseDriver() {driver.quit()} ;

56

Exercices

● Exercices sur Wiki– http://forge.fil.univ-lille1.fr/OTI/wiki/TestsSelenium

– http://forge.fil.univ-lille1.fr/OTI/wiki/TestsSeleniumWebDriver

● Travailler sur les tests pour votre projet JavaScript

57

Outils de Tests d'Interface

a) Plateformes de tests : JUnit, PHPUnit, Qunit

b) Selenium

c) Outils de déploiement : maven

d) Outils de qualité : sonar

http://www.fil.univ-lille1.fr/~bilasco/OTI/OTI2014a.pdf

58

Systèmes de déploiement

(GNU) MakeCompilation & dépendances

(Apache) AntCompilation & dépendances & tâches

(Apache) MavenDépendances symboliques

Structuration des projets en familles

Automatisation

Plugins dédiés pour :

distribution : Jar, Ear, War, Aar

tests : surfire

sonar : sonar

scv : maven-scm-plugin

59

Maven

●Proposer un système de build universel

●Un cadre type pour la construction de projet

●Organiser les projets de manière hierarchique ● GroupID/ArtifactID/Version● Réutilisation à tout prix● Héritage entre projets

●Aider dans la gestion des distributions et suivi de bugs●Management de distributions – intégration SCM ●Management de dépendances

60

Maven

●Proposer un système de build universel

●Un cadre type pour la construction de projet

●Organiser les projets de manière hierarchique ● GroupID/ArtifactID/Version● Réutilisation à tout prix● Héritage entre projets

●Aider dans la gestion des distributions et suivi de bugs●Management de distributions – intégration SCM ●Management de dépendances

61

Maven – fonctionnalités

Proposer des lignes de conduites pour un développement optimal

Structure de projets prédéfinie

Séparation entre sources (main) et tests (test)

- src/ - main/

- java/ - ressources/ - config/ - test/ ...

- target/ ...- pom.xml

62

Maven - POM

POM ou "Project Object Model"● Représentation XML pour les projets Maven

Un project (Maven) ou archetype contient ● Identification du projet● fichiers de configuration ● développeurs intervenant dans le projet● l'organisation et les licences ● l'URL où est visible le projet ● les dépendances du projet ● les plugins

– SCV, Tests, Système de traçage de bugs ...

63

Maven – POM

<project xmlns="http://maven.apache.org/POM/4.0.0"...> <modelVersion>4.0.0</...>

<!-- The Basics -->

<groupId>...</...> <version>...</...> <packaging>...</...> <dependencies>...</...>

<parent>...</...> <dependencyManagement> … </...> <modules>...</...> <packaging>...</...>

<!-- Build Settings -->

<build>...</build> <reporting>...</reporting>

<!-- More Project Information -->

<name>...</...> <url>...</...> <licenses>...</...> <developers>...</...> <contributors>...</...>

<!-- Environment Settings -->

<mailingLists>...</...> <scm>...</...> <prerequisites>...</...> <repositories>...</...>

<pluginRepositories>...</...> <distributionManagement>...</...> ...

</project>

64

Maven – cycle de vie

65

Maven - cycle de vie

mvn archetype:generate – construction POM + dossiers

mvn validate - POM correctement défini

mvn compile - compile les sources

mvn test - Lance les tests unitaires

mvn package - Prépare la distribution (J/W/Ear)

mvn verify - Tests de validation nv package.

mvn install - Installe le pk en local (dép. int.)

mvn deploy - Déploie le pk sur un serveur

66

Maven & Sonar - exercises

http://forge.fil.univ-lille1.fr/ODEVA/wiki/MavenExo

● Travail sur le projet JUnit

– Creation d'un projet Maven

– Compilation et Tests Unitaires

– Installer SonarQube

– Configurer sonar-project.properties (runner->qube)

– Lancer Analyse

– Faire évoluer votre code

– Re-analyser

67

● … the end

● ...plus loin du contenu supplémentaire

68

Outils de Tests d'Interface

a) Plateformes de tests : JUnit, PHPUnit, Qunit

b) Outils de qualité : sonar

c) Selenium

d) Outils de déploiement : maven

http://www.fil.univ-lille1.fr/~bilasco/OTI/OTI2014a.pdf

69

PHPUnit

● Quasiment même concepts que JUnit

● Code test écrit et exécuté depuis le serveur

– phpunit.phar

● Intégré également dans frameworks (Symfony...)

● Classes de tests étendent

– PHPUnit_Framework_TestCaseclass TestCase1 extends PHPUnit_Framework_TestCase {...}

70

PHPUnit

● Initialisation – setUp{BeforeClass}, tearDown{BeforeClass}

● Asserts de langage – assert{InstanceOf,ClassHasAttribute,ObjectHasAttribute}

– assert{ArrayHasKey, Contains, Count}

– assertString{EndsWith,StartsWith}

● Exceptions – try {opsProduisantExc ; fail ("absence") ;} catch (Exc $e) {}

– $this->setExpectedException(excClassName,excMsg)

– /** * @expectedException Exc_Class_Name */

71

PHPUnit et les applis Web

● Asserts Sortie écran – setExpectedOutput{String/Regexp}

● Asserts orientés Web– XML : assert{EqualXMLStructure,XMLStringEqualsXMLFile,...}

– JSon : assertJsonFileEqualsJsonFile

– CSS : assertSelect{Count,Equals,Regexp}

– HTML : assertTag

● Extensions– PHPUnit/Extensions/Database/TestCase.php

72

PhpUnit

● Générateur de données (@dataProvider) pour simuler RepeatedTest

– function nomF() { return array(array(v1a,v1b),array(v2a,v2b),...)} ;

– /** @dataProvider nomF */ → fournit tableau de params.

– function testXXX($a,$b) {…}–

● Dépendances entres tests – ordonnancer les tests– /** @depends test1 */ function test2() { … }

Test1 * <----- Test2* mettre le système dans l'état attendu par Test2 – pas atomique

* les opérations autres que la cible du Test2 déjà validées

73

PHPUnit – Suite de tests

● Structurer les tests en répertoires– tests_dir

● test1.php● tests_dir2

– test2.php

– $ phpunit tests_dir

● … ou configurer phpunit.xml – <phpunit>– <testsuites>– <testsuite name="ts1">– <directory>Tests</directory>– <file>OtherTests/Test1.php</file>– <exclude>OtherTests/Test2.php</exclude>

– </testsuite>– </testsuites>– </phpunit>

74

PHPUnit Exercices

● http://forge.fil.univ-lille1.fr/OTI/wiki/PHPUnitExo

MoneyFactory.class.php

::+getDefaultFactory+createMoney

Money.class.php

-__construct+getValue +getCurrency

+toString+sameCurrency +equal

MoneyOps.class.php

:: +add

MoneyException.php

IncompatibleCurrenciesExceptionInvalidCurrencyException

InvalidMoneyValueException

MoneyOpsAddTest.php

+testSimpleAdd

MoneySameCurrTest.php

+testSame+testNotSame

MoneyEqTest.php

+testMemeValeurMemeDevise+testMemeValeurDeviseDifff//