Un article parlant de tests unitaires, forcément je le lis. Et vu que celui-ci semblait défendre un point de vue assez iconoclaste je me suis dit que j'allait probablement apprendre quelque chose.
Et bien c'est raté … L'article alterne remarque idiotes et regard condescendant sur les développeurs sans vraiment apporter d'argument pertinent. Et l'article est de moins en moins intéressant a mesure qu'on avance …
Morceau choisis, avec mes commentaires
(remember that we don’t test classes and we don’t even test objects — the unit of functional test is a method)
Alors soit du fait de la POO sans vraiment savoir pourquoi et juste pour faire comme tout le monde (typiquement, tu fais du Java), soit tu fais vraiment n'importe quoi dans tes tests …
Few developers admit that they do only random or partial testing and many will tell you that they do complete testing for some assumed vision of complete. Such visions include notions such as: "Every line of code has been reached," which, from the perspective of theory of computation, is pure nonsense in terms of knowing whether the code does what it should
Ça clairement je suis d'accord avec ça : le code coverage ne garanti rien. La seule garantie c'est de regarder la liste des tests et de vérifier que tous les scénarios possibles sont testés. (attention c'est l'un des seuls trucs sensés écrits dans cet article)
Be humble about what your unit tests can achieve, unless you have an extrinsic requirements oracle for the unit under test. Unit tests are unlikely to test more than one trillionth of the functionality of any given method in a reasonable testing cycle. Get over it.
Je n'aime pas ce genre d'argument (pourtant très fréquent en informatique): Ce n'est pas parce qu'il y a une majoration du nombre de combinaisons possible, qu'il y a besoin d'atteindre cette valeur de majoration pour avoir un test pertinent.
Il y a 4 milliards d'entiers sur 32 bits, pourtant pour tester une fonction qui fait une somme, il n'y a pas besoin de tester les 4 milliards de valeurs: il suffit de voir ce qui se passe en cas normal, et en cas d'overflow. Les sommes «3 + 4» et «25 + 35» sont logiquement identiques, inutile de les tester séparément. Après, il y a plein de cas où lister toutes les possibilités logiques différente est difficile, et ou cette liste peut être très longue, mais ça ne veut pas dire que ça n'est pas faisable dans le cas général.
Large functions for which 80% coverage was impossible were broken down into many small functions for which 80% coverage was trivial. This raised the overall corporate measure of maturity of its teams in one year, because you will certainly get what you reward. Of course, this also meant that functions no longer encapsulated algorithms. It was no longer possible to reason about the execution context of a line of code in terms of the lines that precede and follow it in execution, since those lines of code are no longer adjacent to the one you are concerned about. That sequence transition now took place across a polymorphic function call — a hyper-galactic GOTO. But if all you’re concerned about is branch coverage, it doesn’t matter.
What ? Le mec est-il sérieusement en train de faire l'apologie des fonctions complexes, avec des conditions et des boucles imbriquées ?! Dans un article datant de 2014 ?
I define 100% coverage as having examined all possible combinations of all possible paths through all methods of a class, having reproduced every possible configuration of data bits accessible to those methods, at every machine language instruction along the paths of execution.Anything else is a heuristic about whichabsolutely no formal claim of correctness can be made
C'est juste bête, et faux en pratique pour la plupart des situations du monde réel. (c.f. plus haut)
Tests should be designed with great care. Business people, rather than programmers, should design most functional tests
Ça c'est à la fois vrai et faux: si par «business people» il pense «des gens qui comprennent tous les tenants et les aboutissants du métier pour lesquels l'application est conçue» alors oui je suis d'accord, mais il ne faut pas que ça soit des «business people» au sens de gens ont fait une école de commerce ou de management et qui font de la gestion de projet en comprenant superficiellement le métier dans lequel ils évoluent.
Programmers have a tacit belief that they can think more clearly (or guess better) when writing tests when writing code, or that somehow there is more information in a test than in code. That is just formal nonsense.
Mais ce type a-t-il déjà codé ? Évidemment qu'il y a plus d'information dans les tests que dans le code, dans les tests le CONTEXTE est explicite ! Tout le cheminement est détaillé avec les résultats attendus à chaque étape. Évidemment d'un point de vue logique ça contient la même «information», mais du point de vue de la capacité humaine de compréhension de cette information, ça change du tout au tout !
Maybe all a function does is sets X to 5, and I'll bet there's a test of that function to see if the value of X is 5 after it runs. Good testing, again, is based on careful thought and on basic principles of risk management. Risk management is based on statistics and information theory; if the testers (or at least the test manager) don't have at least rudimentary skills in this area, then you are likely to do a lot of useless tests.
VRAIMENT ? Tu as besoin d'une formation en «statistics» et en «information theory» pour savoir que tester un couple getter/setter est bête et inutile ? Mais il prend vraiment les gens pour des cons !
Let's dissect a trivial example. The purpose of testing is to create information about your program. (Testing does not increase quality; programming and design do.)
En pratique c'est faux, parce qu'en testant son code, on le manipule directement, on le touche du doigt, et ça aide à ce rendre compte plus facilement des design bancale, du code couplé à d'autre choses, etc.
So when they wrote their first function for this project three years ago they wrote a unit test for it. The test has never failed. The question is: How much information is in that test
Ça c'est un exemple plus intéressant. Parce que justement, la plupart des tests ne passeront jamais dans le rouge mais ce n'est pas pour autant qu'ils sont inutiles :
not be worth the expense of maintaining and running the tests. This is the first set of tests to throw away — whether they are unit tests, integration tests, or system tests. Another client of mine also had too many unit tests. I pointed out to them that this would decrease their velocity, because every change to a function should require a coordinated change to the test. They informed me that they had written their tests in such a way that they didn't have to change the tests when the functionality changed. That of course means that the tests weren't testing the functionality, so whatever they were testing
was of little value.
Lol. Ouais, bosser avec des débiles ça arrive ;)
In most businesses, the only tests that have business value are those that are derived from business requirements. Most unit tests are derived from programmers' fantasies about how the function should work: their hopes, stereotypes, or sometimes wishes about how things should go. Those have no provable value
Ce mec est tellement condescendant avec les développeurs …
If this test fails, what business requirement is compromised? Most of the time, the answer is, "I don't know."
Je ne sais pas dans quel domaine il bosse, mais sur le code sur lequel j'ai bossé la réponse est systématiquement l'une des 3: «le programme va crasher», «l'action de l’utilisateur ne va pas marcher» ou encore «le programme va alors se comporter de manière indéterminée». La 3ème option s'approche un peu d'un «I don't know» à ceci près que je suis sûr que quelque chose va mal se passer, même si je ne sais pas exactement qu'est-ce qui va merder en premier (ce qui rend ce genre de situation d'autant plus effrayante).
It is insufficient to reproduce the state space for just the module or class containing the function or method under test: generally, any change anywhere can show up anywhere else in a program and requires that the entire program can be retested
Euh … Si tu es dans cet état d'esprit là, ça veut dire que tu considères que la séparation en couches d'abstractions des ordinateurs n'est pas fiable et que tu dois tester l'ensemble des combinaisons possible pour l'ensemble des sous-couches de l'environnement dans lequel tu évolue, c'est à dire à minima:
When developers write code they insert about three system-affecting bugs per thousand lines of code. If we randomly seed my client’s code base — which includes the tests — with such bugs, we find that the tests will hold the code to an incorrect result more often than a genuine bug will cause the code to fail
C'est vrai, mais la différence, c'est que dans ce cas le développeur a le retour instantanément: le test est cassé et le bug n'est jamais commité. Contrairement à un bug standard, qui sans test se retrouve en production avant que qui que ce soit l'ait remarqué …
(The ones that really make me laugh are the ones who tell me they are able to forget the assumptions they made while coding and bring a fresh, independent set to their testing effort. Both of them have to be schizophrenic to do that.
=> C'est vrai qu'on a généralement le même regard sur les tests que celui qu'on a sur le développement de la fonctionnalité elle-même. Cependant, les tests rendent ce type de biais bien plus explicite, et du coup la revue de code a plus de chance d'attraper les erreurs qui en découlent.
If you have 200 tests — or 2000, or 10,000 — you’re not going to take time to carefully investigate and (ahem) re-factor each one every time it fails. The most common practice — which I saw at a startup where I used to work back in 2005 — is to just overwrite the old test golds (the expected output or computational results on completion of a given test) with the new results
Testing, you're doing it wrong …
Turn unit tests into assertions
Les assertions c'est cool et c'est bien d'en utiliser. Mais ça n'est absolument pas un potentiel remplacement pour les tests unitaires …
Un commentaire pertinent sur hackernews: https://news.ycombinator.com/item?id=11799791