Introduction
Nous allons voir ensemble, une nouvelle façon de faire des tests. Nous allons installer utiliser un projet php-quickcheck. L’idée ici n’est pas d’écrire des tests, mais demander au logiciel de les générer.
Installation.
Nous allons créer le composer.json
suivant.
1 2 3 4 5 |
|
Puis créer un fichier test.php
.
1 2 3 4 |
|
Un petit composer install
. Et tout est en place.
Exemple N°1
Affirmation
Je vais essayer de prouver que array_merge($list1, $list2) == $list1 + $list2
(ce qui est faux)
Je l’écris dans la fonction suivante
1 2 3 |
|
Mise en place et contre-exemple.
Voici le code
1 2 3 |
|
Gen::ints()->intoArrays()
génère des array avec une taille aléatoire [0, 1], [-15,0,5], ..
que je vais passer à la fonction isEqual
1
|
|
Je vais lancer 102 fois mon test.
Voici ce que me dit le programme dès que je lance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
Le résultat est intéressant, Le logiciel a essayé 3 fois, au troisième essai l’exemple ([1], [-2,1])
donne un cas qui ne marche pas.
Vérifions avec php -a
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Effectivement.. Mais il y a mieux. Le logiciel a fais un shrunk, c’est à dire qu’il a calculé le plus petit exemple possible qui est ([0], [0])
.
Donc la librairie me donne tort et en plus me donne le contre-exemple.
Exemple N°2
Affirmation
J’affirme que (sort (array) == sort(sort(array))
que en gros cela ne sert à rien de trier deux fois un array.
Mise en place
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Je lance le logiciel
1 2 3 4 5 6 |
|
Le logiciel semble d’accord. Il a fait 101 tests, mais il n’a pas trouvé de contre-exemple.
Exemple N°3
Nous allons encoder en run legth encoding
qui est l’actuel encodage des fichiers bitmaps.
Quelque exemples:
1 2 |
|
Il y a 12W
puis 1B
etc .. je compresse ma chaîne de caractères.
Dans l’autre sens
1 2 |
|
Voici une implémentation en php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Mon implémentation est correcte, mais il y a un petit souci. Pouvez vous deviner le souci de mon programme.
A priori $input == decode(encode($input))
Mise en place.
1 2 3 4 5 6 7 |
|
Le logiciel ne tarde pas à trouver le souci
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
La chaîne de caractère "G67k"
ne marche pas, et en fait la chaîne "0"
tout cours ne marche pas.
Conclusion des 3 exemples.
- Je n’ai pas écris de test. C’est le logiciel qui génère les tests.
- Les tests sont aléatoires. Par exemple si j’avais limité à 5 tests l’exemple 3 pourrait passer.
- Si le code ne passe pas le logiciel est capable de réduire jusqu’à trouver un contre-exemple ici la chaine
"0"
ou l’entrée([0],[0])
- Un autre cas, dans le dernier exemple, j’ai pris un générateur de texte qui prend des chiffres et des lettres, si j’avais pris un générateur de lettre seulement comme
gen::alphaString
. Le test passerait sans problème.
Ce type de logiciel s’appelle le QuickCheck du nom du premier logiciel en Haskell. Ce sont des tests aléatoires.
Il existe deux portage en php.
Il y a le même problème que les tests unitaires: Quand les tests unitaires ne passent pas, il y a un problème. Mais des tests unitaires qui passent ne prouve pas forcement que le logiciel est correct. Néanmoins cette méthode qui génère des milliers de tests donne des résultats assez intéressants. La capacité a trouvé automatiquement un contre-exemple (s’il y a un contre-exemple) est vraiment un plus.
Cela n’a pas été évident d’écrire ce post. J’ai eu un peu de mal à trouver un exemple pertinent. Je me suis inspiré des exemples de hypothesis. L’implémentation du RLE viens de rosetta mais l’exemple en php est obsolète (la regex /../e
php5.5 n’en veux pas). J’ai retraduis le code.