web-dev-qa-db-fra.com

Comment écrire mon propre test unitaire?

J'essaie actuellement d'écrire un test unitaire de ma part. Le test unitaire que j'écris est principalement pour l'algèbre linéaire (je sais qu'il existe un excellent package mais je veux utiliser le mien pour mon projet). Mon algèbre linéaire actuelle se compose de my_vector.hpp/cpp (3d) et my_matrix.h/cpp.

Je suis donc en train d'écrire un test_vector.cpp Et test_matrix.cpp Qui testera les fonctionnalités de my_vector et my_matrix.

En ce qui concerne les tests de la classe vector, dans test_vector.cpp, je teste les fonctionnalités d'ajout, de soustraction, de division, de dotproduct, etc. de my_vector.

Comment je fais:

// test_vector.cpp
void test_add(){

    my_vector a(2.0, 1.1, 2.1);
    my_vector b(2.1, 2.0, 1.1);

    // manually computed by adding a and b by hand
    // 
    my_vector expected(4.1, 3.1, 3.2);


    my_vector c = a + b;

    assert(c.x == expected.x);
    assert(c.y == expected.y);
    assert(c.z == expected.z);
}

void test_sub(){

    .....
}

int main(){
    test_add();
    test_sub();
    ....
return 0;
}  

Je fais de même pour test_matrix.cpp.

Dans my_vector expected(4.1, 3.1, 3.2); j'ai d'abord ajouté manuellement 2.0, 1.1, 2.1 de a et 2.1, 2.0, 1.1 de b, puis comparé à la valeur calculée après avoir utilisé c = a + b. Pensez-vous que c'est une bonne façon de faire des tests unitaires. Je trouve cela peu fastidieux car je dois faire le calcul à la main pour d'autres tests complexes comme la rotation, le produit croisé, etc. Ce genre de sentiment donne l'impression que je fais quelque chose de mal.

Est-ce que je fais quelque chose de mal? Veuillez me le faire savoir, je suis ouvert à toutes suggestions.

7
solti

C'est une façon assez courante de le faire, et je ne le décrirais pas comme faux . Il existe cependant des alternatives - par exemple, vous pouvez trouver un autre calcul que vous pouvez appliquer aux résultats, qui devrait être plus simple à calculer et montrerait qu'il est correct. De plus, ce n'est probablement pas faisable, mais pour une rotation d'environ 90 degrés, vous pourriez envisager d'appliquer un produit scalaire et de vérifier son zéro, et de vérifier que la magnitude est correcte, et cela vous donnerait une très bonne idée que la mise en œuvre est correcte ( en supposant que votre implémentation de ces autres opérations plus simples est déjà connue pour être correcte).

Vous pouvez aller plus loin et exécuter de tels calculs sur des données aléatoires . Faire cela sur un grand nombre d'éléments peut vous donner l'assurance que vous avez détecté tous les cas Edge dans un algorithme.

Un autre conseil: je remarque que vous n'utilisez pas un framework de tests unitaires. Bien que cela soit possible, je suggère fortement d'utiliser un cadre car ils fournissent de bien meilleurs commentaires en cas de problème. Pour C++, j'ai tendance à utiliser Catch mais il existe également de nombreuses autres alternatives.

5
Periata Breatta

L'utilisation d'un cadre de tests unitaires est un conseil (très) judicieux, comme l'a souligné Pariata Breatta. Il facilite les tests et est pris en charge par de nombreux IDE.

Envisagez de placer le test d'égalité dans votre classe vectorielle elle-même, ce qui facilitera sa réutilisation dans les tests unitaires plus tard - et il sera très probablement très utile tôt ou tard de toute façon. Oh, écrivez également un test unitaire non récursif pour cela. La vérification de tous les composants est généralement la voie à suivre, et en utilisant votre nouvelle méthode, il n'aura besoin que d'une assertion pour cela. La simple comparaison des sommes introduit de nouveaux points de défaillance possibles (pensez à la permutation ou aux erreurs numériques).

Vous voudrez peut-être fournir une vérification "à peu près égale" prenant en charge un epsilon autour de vos valeurs pour permettre des effets d'imprécision numérique, car travailler avec des nombres à virgule flottante pourrait ne pas finir comme vous vous attendez.

2
Eiko

Tu le fais bien. La seule alternative que je peux voir à l'approche manuelle serait d'utiliser une bibliothèque tierce de confiance pour exécuter vos calculs, puis demander à la suite de tests de comparer vos calculs avec ceux de la bibliothèque.

Bien sûr, il serait redondant d'implémenter les fonctionnalités d'une bibliothèque à laquelle vous avez déjà accès. J'imagine que vous ne feriez cela que si la bibliothèque ne peut pas, pour une raison quelconque, être utilisée lorsque vous êtes en ligne et que vous êtes obligé d'implémenter la vôtre.

Soit dit en passant, le résultat attendu ne devrait-il pas être (4.1, 3.1, 3.2)?

1
Eren

Utilisez Google Test framework. Pour se moquer, il y a aussi Google Mock framework . Les deux sont destinés à être utilisés avec C++.

1
Eternal21