Un peu de contexte: un peu plus tôt dans la journée, j'ai dû mettre à jour le code SQL fourni par un autre de mes collègues. Comme il s'agit d'un script assez volumineux, il est stocké dans un fichier séparé (qui est ensuite lu et exécuté à l'exécution). Ce faisant, j'ai accidentellement réintroduit deux bogues remontant à quelques mois, à savoir:
- Pour une raison quelconque, le fichier ASCII a été encodé en UTF-16 (le collègue m'a envoyé le fichier par courrier électronique, ce qui aurait pu le provoquer).
- Le script manquait dans les
SET
instructions initiales (requis en raison de certains éléments du pilote en production, mais pas lors d'une installation propre localement).
Après avoir débogué cela pendant environ une heure (encore), j'ai décidé d'écrire des tests unitaires pour s'assurer que cela ne se reproduirait plus jamais (et d'inclure un moyen rapide de le corriger dans le message d'assertion afin de fournir une solution simple aux futurs développeurs).
Cependant, lorsque j'ai appliqué ce code, un autre collègue (qui est également notre chef d'équipe) s'est approché de moi et m'a dit que je ne devrais plus refaire ces choses parce que:
"Ces choses ne font pas partie des tests unitaires"
"Les tests unitaires ne doivent être utilisés que pour vérifier le flux de votre code"
Je suis assez en conflit maintenant car je pense toujours que ce que je fais n'est pas faux, car ce bogue ne serait pas réintroduit à l'avenir. Cependant, ce collègue travaille en tant que senior et décide en fin de compte de ce que nous passons notre temps dessus. Que devrais-je faire? Ai-je tort de le faire de cette façon? Est-ce considéré comme une mauvaise pratique?
la source
Réponses:
Très probablement, les tests que vous avez écrits sont plus proches des tests d'intégration ou de régression que des tests unitaires. Bien que la ligne puisse être très floue et qu’il y ait parfois de la confusion dans le pédantisme pour ce qui est ou non un test unitaire, je reviens vers votre collègue pour vous demander où devraient être les tests que vous avez écrits, car ils apportent une valeur ajoutée en garantissant l’exactitude du code.
Je ne me concentrerais pas trop sur ce qui est ou n’est pas un test unitaire et réaliserais que même si c’est un test d’intégration, le test pourrait toujours avoir de la valeur.
la source
Techniquement, ce n'est pas un test unitaire, mais plutôt une étape de validation. La bonne approche dépend vraiment de ce que votre flux de travail doit être. Le chef d’équipe a raison sur l’utilité des tests unitaires. Mon sentiment est qu'il s'agit d'utiliser le mauvais outil pour un travail qui reste à faire. Alors commencez par ceci:
Selon la description, vous devez vérifier que tous les scripts de base de données sont conformes à certaines normes.
La qualité du code source est généralement contrôlée par des outils d' analyse statiques . Si vous ne disposez pas d'un outil d'analyse statique pour valider votre code SQL, vous pouvez créer un outil rapide et sale qui effectue la vérification de tout fichier SQL qui lui est transmis. Il n’est pas inutile de vérifier s’il existe des outils d’analyse statique capables de traiter les problèmes dont vous parlez.
Si vous intégrez cette partie de votre infrastructure de génération, par exemple en l’intégrant à Jenkins, vous pouvez l’appliquer à tous les fichiers SQL de votre projet.
Les tests unitaires ne résolvent que le problème de votre fichier actuel.
C'est assez facile, vous parlez à votre chef d'équipe. Il peut travailler avec le propriétaire du produit et avec vous pour déterminer le risque / avantage d’investir dans l’outillage. S'il s'agit probablement d'un problème ponctuel, l'outillage sera probablement excessif. Si l’outillage permettant d’attraper les plus gros problèmes est facile, cela vaut peut-être la peine, rien que pour le contrôle de cohérence.
Votre chef d'équipe peut avoir des idées que vous (ou moi) n'avons pas prises en compte, qui peuvent résoudre le problème plus correctement.
la source
Il est déconseillé d’appeler des tests qui accèdent aux fichiers "Tests unitaires".
Malheureusement, les types de tests existants et leur organisation sont entièrement spécifiques à l'entreprise. Vous devrez donc savoir comment votre entreprise gère ces tests.
Si vous ne disposez pas encore d'un moyen d'exécuter des tests automatisés autres que les tests unitaires, l'approche pragmatique consiste à marquer les tests unitaires qui ne sont pas réellement des tests unitaires avec un préfixe, jusqu'à ce que vous en ayez assez pour commencer à déterminer quel type de test. tests que vous avez réellement / besoin. Après cela, vous pouvez commencer à vous organiser.
la source
Michael Feathers dit ceci dans son livre Travailler efficacement avec Legacy Code:
Votre test aidera-t-il à localiser rapidement les erreurs et à les exécuter rapidement? Si oui, alors fais-le! Si non, alors ne le faites pas! C'est aussi simple que ça!
Cela étant dit, vous travaillez dans un environnement avec d’autres personnes et devez vous entendre avec elles. Vous devrez peut-être le faire à sa manière, même si vous n'êtes pas d'accord avec cela en privé.
la source
J'ai parfois écrit des tests similaires sur des fichiers de code source, des fichiers de configuration, etc. Je ne les appellerais pas des tests unitaires car (a) ils accèdent au système de fichiers et peuvent ne pas être ultra-rapides (b) Peu m'importe qu'ils soient exécutés à chaque enregistrement (par Serveur CI).
Vous pourriez les appeler des tests d'intégration; ils sont certainement plus proches de cette perspective que les tests unitaires.
Mon propre terme pour eux est des tests de ressources . À mon humble avis, ils sont entièrement justifiés s’ils sont exécutés de nuit sur un serveur CI: les coûts sont minimes et, s’ils sont utilisés judicieusement, ils apportent clairement une valeur ajoutée. Une définition de judicieusement : si le test vérifie un problème qui a provoqué un problème (tel que le codage que vous avez mentionné).
la source
Un test unitaire consiste à tester une méthode ou une «unité» de code. Vous testez le plus petit groupe de logique et de code dans votre logiciel.
Plus tard, lorsque vous rejoindrez cette unité avec d’autres unités, vous effectuerez des tests d’intégration.
J'espère que votre chef d'équipe a encouragé votre initiative et aurait dû proposer d'autres suggestions. Vous avez certainement la bonne idée.
Votre code SQL est un code comme n'importe quel langage de génération inférieure tel que C # ou Java et doit être testé en tant que tel. Et la vérification et la validation appartiennent à tous les niveaux de test. Donc, les instructions d'encodage et SET sont incluses, mais ne sont pas nécessairement testées exclusivement. Des éléments généraux tels que les fins de ligne ou les entourages, vous pouvez généralement simplement utiliser un hook ou une fonctionnalité SCM.
La meilleure pratique consiste à avoir des tests de régression pour s'assurer que les anciens bugs ne sont pas réintroduits. Généralement, les tests sont créés parallèlement à toute résolution du bogue. Si ces bogues ne sont pas couverts par les tests de régression au niveau unité / intégration ou système, puis réintroduits, il s'agit d'un problème d'équipe, d'un problème de processus et non d'un problème individuel.
Le problème est que ... les erreurs de syntaxe, les instructions manquantes ou les blocs logiques au sein d'une "unité" ne sont généralement pas testés. Vous testez les entrées et les sorties de l'unité selon différentes combinaisons, en testant les nombreuses possibilités pouvant être générées.
Pour en revenir aux instructions SET manquantes, elles aident à informer les nombreuses possibilités d’entrée et de sortie à tester. Quel test écririez-vous qui échouerait s'il vous manquait un SET choisi?
la source
Si des fichiers font partie de votre produit, leur contenu doit être correct. Aucune raison pour laquelle vous ne voudriez pas vérifier cela. Par exemple, si vous avez besoin de six images 1024x 1024 dans un dossier, alors écrivez un test unitaire qui vérifie que vous avez bien cela.
Mais vous n'avez probablement pas que les fichiers, vous avez aussi du code qui lit les fichiers. Vous pouvez écrire un test unitaire pour ce code. Dans l'exemple ci-dessus, la fonction de lecture de l'une des six images renvoie-t-elle une image de 1024 x 1024 en mémoire (ou quoi que cela soit supposé produire).
Quoi qu’il en soit, il ne s’agit peut-être pas d’un test unitaire, mais c’est un test utile. Et si vous utilisez un framework de test unitaire qui vous permet de faire un test utile (ce n’est pas un test unitaire), pourquoi ne pas utiliser le framework de test unitaire?
la source
Je comprends peut-être mal votre problème, mais pour moi, cela ressemble à un problème qui ne devrait pas nécessairement être capturé par un test spécifique, mais simplement par le système de contrôle de version . Toute modification apportée à une base de code doit être examinée patch par patch avant d'être validée. Un moyen simple de faire cela dans git est d’ajouter les modifications avec
Pour chaque modification dans un fichier texte, le répertoire de travail vous demandera si vous souhaitez réellement le conserver. Cela vous permettrait de voir, par exemple, la suppression de ces «
SET
déclarations initiales ».Si le codage de tout un fichier était modifié, quelque chose de différent se produirait cependant: l'algorithme ne parviendrait pas à différencier l'ancien et le nouveau fichier et, par conséquent
git add -p
, n'ajouterait rien. Ce serait alors visible dans l'autre commande que je ferais avant tout commit, à savoirIci , vous verriez le fichier en rouge, ce qui indique qu'il ya des changements. Enquêter sur les raisons pour lesquelles ils ne l’ont pas fait
git add -p
rendrait rapidement le problème évident.la source
git
est le meilleur exemple de cela - un excellent outil, mais à peine inutilisable pour les simples mortels .Un autre angle à considérer: étant donné que ces deux conditions sont des conditions indispensables à l’exécution de votre programme, ne devriez-vous pas intégrer la logique près de la logique d’exécution? Je veux dire: vous testez l’existence d’un fichier avant de le lire et / ou vous validez son contenu, non? Alors, en quoi est-ce différent? Je pense que puisqu'il s'agit d'une ressource externe au code, elle devrait être validée au moment de l'exécution, avant qu'elle ne soit réellement utilisée. Résultat: application plus puissante, pas besoin d'écrire des tests supplémentaires.
la source
Les tests ont le même code que tous les autres et, s'ils sont suffisamment complexes, bénéficient également de ... tests unitaires. Il semble plus simple d'ajouter de tels contrôles préalables directement dans le test.
La plupart des tests sont assez simples pour ne pas l'exiger, mais si certains sont suffisamment complexes, je ne vois rien de fondamentalement faux avec ces vérifications de précondition. Bien sûr, le test devrait également échouer sans eux, mais un bon test d'unité indique également quelle unité est en train d'échouer.
Un script utilisé dans le cadre du test et qui doit avoir un certain contenu et le codage est probablement une unité. Il peut avoir beaucoup plus de code et de logique que le reste du test. Un test avec un tel script n'est pas la meilleure conception de tous les temps et, si possible, devrait être reformulé en quelque chose de plus direct (sauf s'il s'agit d'un test d'intégration).
la source
Premièrement, l'un des objectifs des tests est d'empêcher que des problèmes ne se reproduisent dans votre code. Vous devez donc absolument continuer à écrire des tests de cette nature.
Deuxièmement, il est difficile de nommer. Oui, ce ne sont clairement pas des "tests unitaires", mais ils peuvent être des éléments souhaitables et nécessaires du processus de construction, car ils vous protègent contre les erreurs évidentes, et parce qu'ils vous informent plus tôt des erreurs conséquences sur une boîte de dev).
La question est donc (devrait être dans votre contexte) plus de savoir quand et comment ces tests sont exécutés que ce qu’ils sont.
J'ai utilisé ce type de test de manière intensive par le passé - ils nous ont évité une bonne partie de la douleur.
la source
Les tests unitaires consistent à exécuter une unité de code de manière isolée pour confirmer qu'elle produit le résultat correct pour l'entrée correcte. L’isolation doit permettre à l’unité testée et au test lui-même de se répéter, c’est-à-dire qu’ils ne doivent pas dépendre d’effets secondaires ni y être associés.
SQL n'est pas exactement quelque chose qui peut être testé isolément. Par conséquent, tout test de SQL n'est pas exactement un test unitaire et, à l'exception des instructions SELECT, il est presque certain qu'il aura un effet secondaire. Nous pouvons appeler cela un test d'intégration plutôt qu'un test unitaire.
Il est toujours sage de s'assurer que tout défaut qui pourrait être introduit peut être détecté le plus tôt possible dans le cycle de développement, et il est donc utile de le faire d'une manière qui facilite l'identification de la source du défaut afin qu'il puisse être rapidement détecté. corrigée.
Les tests en question peuvent être plus judicieusement délocalisés du corps des "tests unitaires" et placés ailleurs, mais ils ne doivent pas être totalement supprimés s'ils servent à quelque chose d'utile, comme se prémunir contre l'introduction éventuelle d'un défaut qui pourrait prendre des heures à suivre. vers le bas.
la source