2011-07-26 1 views
2

J'ai une fonction C++ qui renvoie une ligne multiple std::string. Dans le cas de test pour cela, je compare chaque ligne contre la valeur connue - quelque chose comme:Diff-chaîne de base pour le cas de test C++

std::string known = "good\netc"; 
std::string output = "bad\netc"; 

std::vector<std::string> knownvec; 
pystring::splitlines(known, knownvec); // splits on \n 

std::vector<std::string> outvec; 
pystring::splitlines(output, outvec); 

CHECK_EQUAL(osvec.size(), resvec.size()); 

for(unsigned int i = 0; i < std::min(outvec.size(), knownvec.size()); ++i) 
    CHECK_EQUAL(pystring::strip(outvec[i]), pystring::strip(knownvec[i])); 

Cela fonctionne, mais disons une seule nouvelle ligne est ajoutée, toutes les assertions CHECK_EQUAL suivantes échouent, ce qui est de faire la sortie est difficile à lire

Existe-t-il un meilleur moyen de comparer les deux chaînes, idéalement de façon autonome (ie ne pas lier avec giantdifflib, ou écrire les chaînes dans un fichier et appeler la commande diff!)

[Editer] J'utilise OpenImageIO's rather simple unittest.h

Les données comparées sont principalement des tables YAML ou des tables de recherche de couleurs. Here's an example test case - essentiellement quelques lignes d'en-têtes, puis beaucoup de chiffres:

Version 1 
Format any 
Type ... 
LUT: 
Pre { 
    0.0 
    0.1 
    ... 
    1.0 
} 
3D { 
    0.0 
    0.1 
    ... 
    1.0 
} 
+1

Quelle structure de test unitaire utilisez-vous? –

+0

Si une correspondance de chaîne unique échoue, voulez-vous "resynchroniser" la chaîne correspondant plus bas comme le fait "diff"? –

+0

Il utilise UnitTest ++, ce qui est génial. En aparté, vous ne devez pas omettre les parenthèses de portée autour d'une macro. Utilisez pour (;;) {CHECK_EQUAL (...); } au lieu de (;;) CHECK_EQUAL (...); –

Répondre

1

La meilleure chose à faire serait de sortir de la boucle lorsque les chaînes ne match plus:

for(unsigned int i = 0; i < std::min(outvec.size(), knownvec.size()); ++i) 
{ 
    bool areEqual = pystring::strip(outvec[i]) == pystring::strip(knownvec[i]); 
    CHECK_EQUAL(pystring::strip(outvec[i]), pystring::strip(knownvec[i])); 
    if (!areEqual) 
     break; 
} 

Si CHECK_EQUAL retours une valeur booléenne, alors vous pouvez évidemment simplifier un peu l'exemple ci-dessus. Si vous voulez que votre infrastructure de test unitaire fournisse la même sortie que diff lorsque vous comparez des chaînes multilignes, je crains que vous n'attendiez trop de votre infrastructure de test unitaire. Si vous ne voulez pas créer de lien vers une bibliothèque externe, ou exécuter diff à partir de votre programme de test, vous devrez vous-même programmer un type d'algorithme diff.

Découvrez cette autre question sur les informations sur les algorithmes et bibliothèques diff.

Si vous trouvez que l'implémentation d'un algorithme diff ne vaut pas le coup (ce n'est probablement pas le cas), consultez les bibliothèques Google Diff-Match-Patch.

0

Un algorithme diff de base est plutôt facile à implémenter, voire terriblement efficace. This Wikipedia article est un bon point de départ.

1

court:

Aux fins de tests unitaires, il vous suffit de signaler qu'ils sont différents. Les tests unitaires ne corrigent pas les tests unitaires défaillants, les programmeurs corrigent les tests unitaires défaillants.

Long:

Si vos tailles de séquence sont peut-être différents, il n'y a pas un moyen simple, générique de les comparer. Je pense que vous aurez besoin d'un giantdifflib pour le faire mal, et encore moins adéquatement.

Je pense que si vous ne pouvez pas dire que l'ordinal n'est pas une identité, alors vous devrez utiliser search pour ajouter des informations.

Tenir compte ce cas dégénérative:

a b c d e f 
d e f a b c 

Si oui ou non vous choisissez l'une de ces solutions va baisser de marquer les résultats ou un artefact de la mise en œuvre:

 a b c d e f 
d e f a b c 

a b c d e f 
     d e f a b c 

Mon L'opinion est que si vous devez attribuer une note à un résultat, il est peu probable qu'un test unitaire soit applicable.

Comparer les conteneurs n'est pas très facile en général, si le résultat ne peut pas être trié lexicographiquement, je ne suis pas sûr que tout résultat de calcul sera informatif au-delà de vous dire que c'est différent.

C'est un problème amusant à considérer de toute évidence, mais il est probablement hors de portée des tests unitaires.

Questions connexes