Voici un exemple de base de ce que doit être mon test unitaire, en utilisant qunit:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" href="qunit/qunit-1.13.0.css">
<script src = "qunit/qunit-1.13.0.js"></script>
<script src = "../js/fuzzQuery.js"></script>
<script>
test("Fuzz Query Basics", function()
{
equal(fuzzQuery("name:(John Smith)"), "name:(John~ Smith~)");
equal(fuzzQuery("name:Jon~0.1"), "name:Jon~0.1");
equal(fuzzQuery("Jon"), "Jon~");
//etc
}
);
</script>
</head>
<body>
<div id="qunit"></div>
</body>
</html>
Maintenant, je pensais que c'était un peu répétitif.
Pourrait mettre toutes les entrées / sorties dans un tableau et les parcourir.
test("Fuzz Query Basics", function()
{
var equals = [
["name:(John Smith)", "name:(John~ Smith~)"],
["name:Jon~0.1", "name:Jon~0.1"],
["Jon", "Jon~"]
];
for (var i = 0; i<equals.length; i++)
{
equal(fuzzQuery(equals[i][0]), equals[i][1]);
}
}
);
Et cela fonctionne bien.
Le seul avantage auquel je peux penser pour cette deuxième méthode, c'est que s'il s'avère que vous ne voulez pas vraiment l'utiliser, equal
il est plus facile de faire ce changement en un seul endroit.
En termes de lisibilité, je ne pense pas que ce soit concluant dans les deux cas, même si je préfère probablement la seconde.
En le résumant davantage, vous pouvez placer les cas d'entrée / sortie dans un fichier CSV séparé, ce qui pourrait le rendre plus facile à modifier.
La question est - quelles sont les conventions générales concernant l'écriture de ces types de tests unitaires?
Y a-t-il une raison pour laquelle vous ne devriez pas les mettre en tableaux?
la source
Réponses:
Vos tests refactorisés ont une odeur: logique de test conditionnelle .
Les raisons pour lesquelles vous devez éviter d'écrire une logique conditionnelle dans vos tests sont doubles. Le premier est qu'il sape votre capacité à être sûr que votre code de test est correct, comme décrit dans l'article lié des modèles xUnit.
La seconde est qu'elle obscurcit la signification des tests. Nous écrivons des méthodes de test parce qu'elles mettent la logique pour tester un comportement donné en un seul endroit, et nous permettent de lui donner un nom descriptif (voir l'article BDD original de Dan North pour une exploration de la valeur des bons noms pour les tests). Lorsque vos tests sont cachés dans une seule fonction avec une
for
boucle, cela masque la signification du code pour le lecteur. Non seulement le lecteur doit comprendre la boucle, mais il doit également démêler mentalement tous les différents comportements testés dans la boucle.La solution, comme toujours, est de monter d'un niveau d'abstraction. Utilisez un cadre de test qui vous donne des tests paramétrés , comme le font xUnit.NET ou Contexts (avertissement: j'ai écrit Contexts). Cela vous permet de regrouper les tests de triangulation pour le même comportement de manière naturelle, tout en séparant les tests des comportements séparés.
la source
Il semble que vous souhaitiez vraiment un test unitaire basé sur les données. Puisque vous avez mentionné l'utilisation de QUnit, j'ai trouvé un plugin qui permet des tests paramétrés:
https://github.com/AStepaniuk/qunit-parameterize
Il n'y a rien de mal idéologiquement avec un test basé sur les données, tant que le code de test lui-même n'est pas conditionnel. En regardant votre code de test, il semble être un très bon candidat pour un test basé sur les données.
Exemple de code pour le fichier LISEZMOI GitHub:
la source
Vous vous répétez moins en utilisant le tableau qui est plus facile à gérer. Une approche que j'aime utiliser est d'avoir une méthode distincte qui organise, agit et affirme les tests, mais accepte les paramètres d'entrée avec lesquels je teste donc j'ai 1 méthode de test par ensemble d'entrées.
Cela me permet de dire instantanément quels tests / entrées échouent.
la source
J'aime votre deuxième approche, mais j'ajouterais 2 points
for
boucles"
Je ne suis pas sûr de qunit, mais un bon testeur vous montrera quelle chaîne d'entrée a échoué et quel était le résultat attendu
la source