95
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/OTI2019a.pdf

Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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/OTI2019a.pdf

Page 2: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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éf ini, développé et livré séparément des tests● src/ vs test/

Page 3: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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écif ications on n'écrit que le code nécessaire à valider les tests

… en TP ?

Page 4: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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.f il.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

Page 5: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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 f in de séances / module)● Evaluations

– Couverture de tests pour les codes WebA/FwkJS

Page 6: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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

Page 7: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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

Page 8: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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 })

Page 9: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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));

}

} .

Page 10: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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.sub(f14EUR);

}

} .

Page 11: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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écif iques 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));

Page 12: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

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//

Page 13: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

13

JUnit et Mock

● Maîtriser le comportement des objets accessoires inclus dansun test unitaire → isoler le comportement à tester

● Disposer des objets à comportement contrôlé

Page 14: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

14

JUnit et Mock (2)

● Automatiser la construction des objets dont le comportementest contrôlé tout en préservant les interfaces logicielles

– renvoie en dur des valeurs pour les méthodes invoquées(STUB)

● Observer le comportement des objets contrôlés (appel deméthode, …)

– vérifier l'utilisation qui en est faite après exécution(SPY)

● … tout en assurant de la transparence d'un point de vueusage : objet et mock ont la même signature

● D'autres utilisations

– Des classes partiellement implémentées

– Disponibilités de ressources limitées (appels WS, BD)

– Etat de systèmes difficilement reproductible in vivo

Page 15: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

15

JUnit et Mockito.org (3a)

● Créer un mock (stub) à partir d'une interface/class

– Interface obj_mock=mock(Interface.class)

– Pas d'état interne → variables membres noninitialisées / méthodes vides

– Remplacer (partiellement) le comportementpar défaut

● doReturn().when(obj_mock).methode() ouwhen(obj_mock.methode()).thenReturn()

● Créer un mock (stub) à partir d'une interface/class

– Interface obj_mock=mock(Interface.class)

– Par défaut, aucun comportement

– Remplacer (partiellement) le comportement normal de la classe

● doReturn().when(obj_mock).methode() ouwhen(obj_mock.methode()).thenReturn()

– Réutiliser comportement normal when().thenCallRealMethod()

X OKX

Page 16: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

16

JUnit et Mockito.org (3d)

● Créer un mock (stub) à partir d'une interface/class

– Interface obj_mock=mock(Interface.class)

– Par défaut, aucun comportement, pas d'état interne

● variables membres non initialisées

– Privilégier l'encapsulation

Page 17: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

17

JUnit et Mockito.org (3b)

X

● Créer un mock (stub) à partir d'une interface/class

– Interface obj_mock=mock(Interface.class)

– Réutiliser comportement normal when().thenCallRealMethod()

● sauf pour hashCode(),equals() ou méthodes private/final

égalité des mocks ou des Money ?

Page 18: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

18

JUnit et Mockito (3c)

● Créer un mock (stub) à partir d'une interface/class

– Interface obj_mock=mock(Interface.class)

– Par défaut, aucun comportement

– Remplacer (partiellement) le comportement initial de la classe

● doReturn().when(obj_mock).methode() ouwhen(obj_mock.methode()).thenReturn()

● sauf pour hashCode(),equals() ou méthodes private/final

Page 19: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

19

JUnit et Mockito (4)

● Créer un mock partiel (spy) à partir d'un objet

– Interface obj_spy=spy(new Classe())

– Etat interne réel

– Remplacer (partiellement) le comportement par défaut

● doReturn().when(obj_spy).methode()

– Réaliser comportement par défaut, change juste le résultat

● when(obj_spy.methode()).thenReturn()

Page 20: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

20

JUnit et Mockito (5)

● Créer un mock partiel (spy) à partir d'un objet

– Interface obj_spy=spy(new Classe())

– Etat interne réel

– Remplacer (partiellement) le comportement par défaut

● doReturn().when(obj_spy).methode()

– Réaliser comportement par défaut, change juste le résultat

● when(obj_spy.methode()).thenReturn()

– Permet de vérifier les appels réalisés sur un objet

● verify(obj_spy).methode() ouverify(obj_spy,times(N)).methode()

Page 21: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

21

JUnit et Mockito (6)

● SimpleAdd example

● Re-écrire certains de vos tests en utilisant des mocks

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

Page 22: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

22

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/OTI2019a.pdf

Page 23: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

23

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/

Page 24: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

24

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

Page 25: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

25

QUnit by JQueryhttp://code.jquery.com/qunit/qunit-qunit-2.0.1.css

http://code.jquery.com/qunit/qunit-2.0.1.js

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

● TestCases

– Synchrones : QUnit.test (nom, funcDef)

– Asynchronnes : QUnit.test(nom, funcDef)

● assert.async() - bloquant / débloquant pour simuler l'attente

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

● QUnit.module("suiteA", setup:function(){...}, teardown:function(){…})

QUnit.test("testA1", function() {...})

QUnit.test("testA2",function() {...})

● TestSuites (npm qunit-composite 2.0.0)

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

● Mocks (Sinon.JS - http://sinonjs.org/releases/sinon-qunit-1.0.0.js)

Page 26: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

26

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

● Assertions

– assert – injecté comme dépendance dans le testQUnit.test("nom test",function(assert) {…}) ;

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

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

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

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

– assert.throws(funcDef,expectedRegExp[,msg]) – test passé siexpected lancée

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

– assert.expect(NbDAssertionsAttendues) ;

Page 27: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

27

QUnit – test & throwsexemples

QUnit.test("test accesseurs", function(assert){ assert.expect(2) ;

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

});

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

QUnit.test("test multi devise add", function(assert){

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

DevisesIncompatibleExc, "Devises Incompatibles");});

Page 28: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

28

QUnit – tests and Ajax … the wrong way

QUnit.module("async");

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

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

Qunit.test("end",function(assert){assert.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

Page 29: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

29

QUnit – tests and AjaxQUnit.module("async");

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

QUnit.test("connect using Ajax",function(assert){ var done = assert.async() ;

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

done(); } } xmlhttp.open("GET","random.php",true); xmlhttp.send(); });

Qunit.test("end",function(assert){assert.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

Page 30: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

30

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.) servantde support pour la réalisation des tests

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

Page 31: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

31

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-2.0.1.css" /><script src="http://code.jquery.com/qunit/qunit-2.0.1.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>

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

QUnit.test("test accesseurs", function(assert){

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

});

Page 32: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

32

Test unitaires – Exos 1

● QUnit

● Commencer à réfléchir à comment mettre en placeles tests sur vos codes WebA/FmwkJS

money.js

money(v,curr)getValue

getCurrrencyequals

money_ops.js

simpleAdd

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

Page 33: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

33

QUnit + SinonJShttp://sinonjs.org/qunit/

● Surveiller et Maîtriser le comportement des objets métiers JS

● Spy = surveiller le comportement (http://sinonjs.org/docs/#spies)

– anonyme : annon = sinon.spy() ou fonction : sinon.spy(obj, 'nom function')

– .calls / .args / .returnValues / .withArgs / .called{Once/Twice.../Before/After} /.calledWith

● Stub = Spy + contrôle sur les résultats (http://sinonjs.org/docs/#stubs)

– anonyme : annon = sinon.stub()

– fonction : sinon.stub(obj, 'nom function') ou sinon.stub(obj, 'nom', nvl_funct)

– object : sinon.stub(obj) ou sinon.createStubInstance(constructor)

– .withArgs / .onCall(n) / .returns / .throws / .restore

● Matchers sinon.match({1/ 'a' / '/^.*$/' /...) / sinon.match.{any/string/...}

● Assertions sinon.assert.*Called* sinon.assert.*Threw* ← incompatible avec QUnit2.0

● Fake Timers / XMLHttpRequest / Server

Page 34: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

34

QUnit + SinonJShttp://sinonjs.org/qunit/support pour Qunit 2.0

● SinonJS conçu pour QUnit 1.x

● Changements QUnit1.x → 2.x https://qunitjs.com/upgrade-guide-2.x/

– 1.x : nombre d'assertions dans l'entête du test

– 1.x : test vs asynchTest

– 1.x : absence d'injection d'assert, ok,equal – globaux

● Adapter qunit-sinon1.0.0 → sinon-qunit 2.0.1

● ! Assertions sinonjs non-fonctionnelles : QUnit.ok → assert.ok

Page 35: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

35

QUnit + SinonJShttp://sinonjs.org/qunit/

Stubs

X

Page 36: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

36

QUnit + SinonJShttp://sinonjs.org/qunit/

Stubs

← m1EUR.equals.restore() ;

Page 37: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

37

QUnit + SinonJShttp://sinonjs.org/qunit/

Stubs

Page 38: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

38

QUnit + SinonJShttp://sinonjs.org/qunit/

Spys

Page 39: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

39

Test unitaires – Exos 2

● QUnit + SinonJS

● Commencer à réfléchir à comment mettre en placeles tests sur vos codes WebA/FmwkJS

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

Page 40: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

40

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");});

Page 41: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

41

● « 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

Page 42: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

42

QUnit

● Tests sur le comportement métier des scripts

● Tests sur le comportement de l'interface

– changements dans le DOM

– apparition des alertes

Page 43: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

43

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'));

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

Page 44: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

44

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

...

Page 45: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

45

Qunit+Sinon.JS+ (window.)alert

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

● Intercepter la fonction window.alert

spy(window,"alert") ; ou stub(window,'alert') ;

● S'assurer qu'elle a été appellée

assert.ok(window.alert.calledOnce)

● Rétablir le comportement de window.alert

window.alert.restore()

...

Page 46: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

46

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

Page 47: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

47

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/OTI2019a.pdf

Page 48: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

48

SONAR

● Outil pour mesurer la qualité du code

Page 49: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

49

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

Page 50: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

50

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

– utiliser karma, karma-qunit, karma-sinon (npm)

– serveur prenant la main sur un ou plusieurs navigateurs :

● karma-{phantomjs|firefox|chrome}-launcher

– configuration du projet (karma.conf.js)

● Récupération des informations de « coverage » ( + Karma-coverage)

● Alimenter SonarQube en utilisant sonar-runner

Page 51: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

51

Sonar et JS

● Configuration Karma

– nodejs node_modules/karma/bin/karma init karma.conf.js– choix framework/browser/sources+tests/ignore_files

● Récupération des informations de « coverage » ( + Karma-coverage)

– pré-processing

● preprocessors: {'src/*.js':['coverage']}

– reporting

● reporters: ['progress','coverage','junit'],coverageReporter: {type: 'lcov', dir: 'reports', subdir: 'coverage'}

● Lier reporting Karma à la configuration Sonar

– sonar.javascript.lcov.reportPath=reports/coverage/lcov.info

Page 52: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

52

Sonar - exercices

● Travail sur le projet Money_JS

– Installer SonarQube

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

– Lancer Analyse

– Installer Karma + Qunit + Sinon + coverage

– Configurer karma.conf.js

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

– Faire évoluer votre code

– Re-lancer l'analyser

Page 53: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

53

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

Page 54: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

54

Tests sans xUnit

2 EUR + 2 EUR

Result : 4 EUR

2 E + 2 EUR

Invalid currency (length!= 3)

-2 EUR + 2 EUR

Invalid value (v > 0)

2 EUR - 2 EUR

Unsupported operation SUB

-2 E + 2 EUR

Invalid value (v > 0)

Page 55: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

55

Tests sans xUnit

Si on rentre 2 EUR, puis 2 EUR, puis on sélectionne l'opération « + » eton demande de calculer, on obtient en vertle résultat « Result : 4 EUR »

Page 56: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

56

Tests sans xUnit

Si on rentre 2 (ds le text v1) EUR (ds le text c1), puis 2 (ds le text v2) EUR (ds le text c2), puis on sélectionne l'opération « + » (ds le select ops) eton demande de calculer, on obtient le résultat « Result : 4 EUR » (ds le div res / style.color=green)

Page 57: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

57

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 ...)

Page 58: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

58

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

Page 59: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

59

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

Page 60: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

60

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

Page 61: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

61

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 lapage – limitez les contraintes de localisation dans le code

Page 62: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

62

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>

Page 63: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

63

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

● 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)

Page 64: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

64

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>

Page 65: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

65

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

Page 66: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

66

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

● Navigateurs 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

Page 67: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

67

Selenium Tests

API.java

SeleniumWeb Driver

server

Android Chrome Firefox

Actions Créer WebDriverExécuter Selenesse

InformerSignaler

Selenium Tests

API.php

Selenium Tests

API.js

RemoteWebDrivers

Page 68: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

68

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}

Page 69: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

69

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()

Page 70: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

70

Selenium Web Driver - RemoteWebDriver

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

– les WebElement sont contrôlables

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

Page 71: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

71

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)

Page 72: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

72

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

Page 73: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

73

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)

Page 74: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

74

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() ;

} }

Page 75: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

75

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()} ;

Page 76: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

76

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 vos codes JavaScript(WebA ou FmwkJS)

Page 77: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

77

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/OTI2017a.pdf

Page 78: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

78

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

Page 79: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

79

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

Page 80: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

80

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

Page 81: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

81

Maven – fonctionnalités

Proposer des lignes de conduites pour undé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

Page 82: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

82

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 ...

Page 83: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

83

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>

Page 84: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

84

Maven – cycle de vie

Page 85: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

85

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

Page 86: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

86

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

Page 87: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

87

● … the end

● ...plus loin du contenu supplémentaire

Page 88: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

88

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/OTI2017a.pdf

Page 89: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

89

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 {...}

Page 90: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

90

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 */

Page 91: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

91

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

Page 92: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

92

PhpUnit

● Générateur de données (@dataProvider) poursimuler 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

Page 93: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

93

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>

Page 94: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

94

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//

Page 95: Outils de Tests d'Interface - FIL Lille 1bilasco/OTI/OTI2019a.pdf · 3 Tests Dans un cadre collaboratif code écrit 1 fois, répliqué n fois Dans un cadre Agile itérations courtes,

95

Test unitaires – Exos 1

● QUnit

● Commencer à réfléchir à comment mettre en placeles tests sur vos codes WebA/FmwkJS

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