27-08-2013, 12:23 PM
Il est facile de voir ce que les preuves apportent, et dans un monde idéal, tout les codes seraient prouvés, et les bugs n'existeraient pas.
Mais dans la réalité, les preuves ont un coût important.
On a déjà évoqué la difficulté de trouver des personnes capable de prouver le code, mais ce n'est pas le seul coût, loin de là: poser une preuve, c'est long.
Le but des tests (unitaires ou non), c'est de réduire le nombre de bug, et ainsi gagner du temps.
On va passer 1h à faire des tests, pour économiser 3 ou 4h de debug, c'est rentable. S'il faut 10h pour faire la preuve formelle, alors c'est une perte de temps, aussi bien pour un pro qu'un amateur.
Comme tu l'as dit, si a() utilise b(), il faut prouver b() pour prouver a(). De ce fait, pour être sur à 100% de la perfection de son programme, il faudrait que le langage sont prouvé, ainsi que toutes ses dépendances, et donc l'OS (et je ne parle même pas du hardware, ce qui est impossible). La perfection n'existe pas.
Concernant ton code de la méthode addToDOM, la méthode
Rajouter des contrôles à tout les niveaux n'est pas une bonne idée: certes tu peut voir les erreurs plus vite, et être sûr du résultat, mais tu perd énormément en lisibilité et maintenabilité.
Tu as multiplié ton nombre de lignes par 5 ! Tu perd également en performance, le temps de vérification n'est jamais nul.
Enfin, dans ce cas, c'est les specs de
Pour le check du parent, l'appel à une méthode qui n'existe pas lancera aussi une exception, donc c'est pas utile.
Bien sur, je ne dit pas que les preuves ne servent à rien, au contraire. Et j'en voit parfaitement l'utilité dans les systèmes critiques (systèmes embarqué pour du médical ou de l'aéronautique par exemple).
Sinon, mis à part cette comparaison test / preuve, il y a d'autres intérêt à utiliser les tests unitaires.
Lorsque j'ai commencé à faire des tests la première fois, j'ai écrit le code d'une classe et testé ensuite.
Quand me me suis mis à tester, j'ai vu plein de détails qui me gênaient dans mon code:
- "Tient, pourquoi je doit coder 4 lignes pour faire ce truc qui va être utilisé de partout, alors qu'avec une autre implémentation je pourrais le faire en 2 ?"
- "Bah alors, utiliser la fonction
L'architecture n'était pas mauvaise au contraire. J'ai bien pensé mes différentes classes et leurs interactions, j'ai un diagramme UML complet et solide.
Ce qui me manquait, c'était "l'ergonomie" du code, la vision qu'aurait l'utilisateur de l'API.
Depuis, je commence toujours pas faire les tests avant de coder.
Mais dans la réalité, les preuves ont un coût important.
On a déjà évoqué la difficulté de trouver des personnes capable de prouver le code, mais ce n'est pas le seul coût, loin de là: poser une preuve, c'est long.
Le but des tests (unitaires ou non), c'est de réduire le nombre de bug, et ainsi gagner du temps.
On va passer 1h à faire des tests, pour économiser 3 ou 4h de debug, c'est rentable. S'il faut 10h pour faire la preuve formelle, alors c'est une perte de temps, aussi bien pour un pro qu'un amateur.
Comme tu l'as dit, si a() utilise b(), il faut prouver b() pour prouver a(). De ce fait, pour être sur à 100% de la perfection de son programme, il faudrait que le langage sont prouvé, ainsi que toutes ses dépendances, et donc l'OS (et je ne parle même pas du hardware, ce qui est impossible). La perfection n'existe pas.
Concernant ton code de la méthode addToDOM, la méthode
appendChild
gère elle-même les cas particuliers que tu propose en lançant des exceptions.Rajouter des contrôles à tout les niveaux n'est pas une bonne idée: certes tu peut voir les erreurs plus vite, et être sûr du résultat, mais tu perd énormément en lisibilité et maintenabilité.
Tu as multiplié ton nombre de lignes par 5 ! Tu perd également en performance, le temps de vérification n'est jamais nul.
Enfin, dans ce cas, c'est les specs de
appenChild
qui sont mal faites: il n'est pas noté qu'elle puisse lancer une exception NOT_FOUND_ERR si l'entrée n'est pas un élément du DOM (alors que c'est le cas pour toutes les autres méthodes travaillant avec des objets du DOM. Chromium le fait).Pour le check du parent, l'appel à une méthode qui n'existe pas lancera aussi une exception, donc c'est pas utile.
Bien sur, je ne dit pas que les preuves ne servent à rien, au contraire. Et j'en voit parfaitement l'utilité dans les systèmes critiques (systèmes embarqué pour du médical ou de l'aéronautique par exemple).
Sinon, mis à part cette comparaison test / preuve, il y a d'autres intérêt à utiliser les tests unitaires.
Lorsque j'ai commencé à faire des tests la première fois, j'ai écrit le code d'une classe et testé ensuite.
Quand me me suis mis à tester, j'ai vu plein de détails qui me gênaient dans mon code:
- "Tient, pourquoi je doit coder 4 lignes pour faire ce truc qui va être utilisé de partout, alors qu'avec une autre implémentation je pourrais le faire en 2 ?"
- "Bah alors, utiliser la fonction
checkMachin
à chaque fois, c'est lourd, ce serait plus simple si la classe lançait une exception toute seule"L'architecture n'était pas mauvaise au contraire. J'ai bien pensé mes différentes classes et leurs interactions, j'ai un diagramme UML complet et solide.
Ce qui me manquait, c'était "l'ergonomie" du code, la vision qu'aurait l'utilisateur de l'API.
Depuis, je commence toujours pas faire les tests avant de coder.