PHPUnit: affirmer que deux ensembles sont égaux, mais l'ordre des éléments n'est pas important
Ce qui est un bon moyen pour affirmer que les deux tableaux d'objets sont égaux, où l'ordre des éléments dans le tableau est sans importance, ou même des sujets à changement?
- Avez-vous des soins sur les objets dans le tableau étant égal ou juste qu'il y a une quantité de x de l'objet o dans les deux tableaux ?
- Les deux serait le plus intéressant. Dans mon cas, si il ya un seul objet o dans chaque tableau.
- veuillez définir l'égalité. Est de comparer triés objet hachages de quoi avez-vous besoin? Vous aurez probablement à objets de toute façon.
- L'égalité comme dans ==. Dans mon cas, ils sont des objets de valeur, donc de la monotonie n'est pas nécessaire. J'aurais probablement pu créer une méthode assert. Ce que j'ai besoin c'est de compter le nombre d'éléments dans chaque tableau, et pour chaque élément à la fois sur l'égalité (==) doit exister.
- Comparateur outils sur PHPClasses
- En fait, sur PHPUnit 3.7.24, $this->assertEquals affirme le tableau contient les mêmes clés et des valeurs, ignorant dans quel ordre.
Vous devez vous connecter pour publier un commentaire.
La façon la plus propre de le faire serait d'étendre phpunit avec une nouvelle affirmation de la méthode. Mais voici une idée pour un moyen plus simple pour l'instant. Code non testé, veuillez vérifier:
Quelque part dans votre application:
Dans votre test:
count(array_diff_assoc($b, $a))
aussi.Vous pouvez utiliser assertEqualsCanonicalizing méthode qui a été ajouté dans PHPUnit 7.5. Si vous comparez les tableaux à l'aide de cette méthode, ces tableaux seront triés par PHPUnit tableaux de comparaison elle-même.
Exemple de Code:
Dans les anciennes versions de PHPUnit vous pouvez utiliser un sans-papiers param $canonicalize de assertEquals méthode. Si vous passer $canonicalize = true, vous obtiendrez le même effet:
Tableaux comparateur de code source à la dernière version de PHPUnit: https://github.com/sebastianbergmann/comparator/blob/master/src/ArrayComparator.php#L46
$delta = 0.0, $maxDepth = 10, $canonicalize = true
passer des paramètres dans la fonction est trompeuse - PHP ne supporte pas les arguments nommés. Ce qui est en train de faire est la définition de ces trois variables, puis immédiatement en passant leurs valeurs à la fonction. Cela va poser des problèmes si ces trois variables sont déjà définis dans la portée locale, car ils seront écrasés.$this->assertEquals($array1, $array2, "\$canonicalize = true", 0.0, 10, true);
. Je pourrais utiliser 4 lignes au lieu de 1, mais je ne l'ai pas fait.sort($array1); sort($array2); $this->assertEquals($array1, $array2);
$this->assertEquals($array1, $array2, "canonicalized contents did not match", 0.0, 10, true);
$canonicalize
sera supprimé: github.com/sebastianbergmann/phpunit/issues/3342 etassertEqualsCanonicalizing()
va le remplacer.Mon problème est que j'ai 2 tableaux (array touches ne sont pas pertinentes pour moi, juste les valeurs).
Par exemple, j'ai voulu tester si
avait le même contenu (afin de ne pas pertinente pour moi) que
J'ai donc utilisé array_diff.
Résultat Final a été (si les matrices sont égales, la différence de résultat dans un tableau vide). Veuillez noter que l'écart est calculé de deux façons (Merci @béret, @GordonM)
Pour un message d'erreur plus détaillé (en cours de débogage), vous pouvez également tester comme cela (merci @DenilsonSá):
Ancienne version avec des bugs à l'intérieur:
$this->assertEmpty(array_diff($array2, $array1));$array1
a plus de valeurs que$array2
, puis il retourne tableau vide, même si le tableau de valeurs ne sont pas égales. Vous devez également tester, la taille de ce tableau est de même, pour être sûr.$a1 = [1,2,3,4,5]; $a2 = [1,3,5]; var_dump (array_diff ($a1, $a2)); var_dump (array_diff ($a2, $a1))
assertEmpty
ne sera pas imprimé le tableau si elle n'est pas vide, ce qui est gênant, alors que les tests de débogage. Je vous suggère de l'aide:$this->assertSame(array_diff($expected, $actual), array_diff($actual, $expected), $message);
, ce qui permettra d'impression les plus utiles message d'erreur avec le minimum de code supplémentaire. Cela fonctionne parce que A\B = B\A ⇔ A\B et B\A sont vides ⇔ A = BArray to string conversion
message lorsque vous essayez de lancer d'un tableau en une chaîne de caractères. Une façon de contourner cela est d'utiliserimplode
Une autre possibilité:
assertEquals
l'ordre n'a pas d'importance.Simple méthode d'assistance
Ou si vous avez besoin de plus d'informations de débogage lorsque les tableaux ne sont pas égaux
Si le tableau est triable, je voudrais trier fois avant de vérifier l'égalité. Si non, je voudrais les convertir en des ensembles, de la sorte, et de comparer ces.
À l'aide de array_diff():
Ou avec 2 affirme (plus facile à lire):
Nous utilisons le wrapper suivant la méthode lors de nos Tests:
Si les touches sont les mêmes, mais de l'ordre de ce qui devrait résoudre cela.
Vous avez juste à obtenir les clés dans le même ordre et de comparer les résultats.
Même si vous ne vous souciez pas de la commande, il peut être plus facile de le prendre en compte:
Essayer:
Les solutions proposées comme ne pas faire le travail pour moi parce que je voulais être capable de gérer un tableau multi-dimensionnel et d'avoir un message clair de ce qui est différent entre les deux tableaux.
Voici ma fonction
Puis de l'utiliser
J'ai écrit un code simple pour d'abord obtenir toutes les clés à partir d'un tableau multidimensionnel:
Ensuite pour vérifier qu'ils ont été structuré de la même quel que soit l'ordre de touches:
HTH
Si les valeurs sont juste des int ou des chaînes, et pas de multiples niveau des tableaux....
Pourquoi ne pas trier les tableaux, les convertir en chaîne...
... et puis comparer chaîne:
Si vous voulez tester que les valeurs de la matrice que vous pouvez faire:
echo("<pre>"); print_r(array_values(array("size" => "XL", "color" => "gold"))); print_r(array_values(array("color" => "gold", "size" => "XL")));
Une autre option, comme si vous ne l'avez pas déjà assez, est de combiner
assertArraySubset
combiné avecassertCount
pour faire de votre affirmation. Donc, votre code devrait ressembler à quelque chose comme.self::assertCount(EXPECTED_NUM_ELEMENT, $array);
self::assertArraySubset(SUBSET, $array);
De cette façon, vous sont indépendants, mais encore affirmer que tous vos éléments sont présents.
assertArraySubset
l'ordre des indices d'importance si ça ne fonctionnera pas. c'est à dire self::assertArraySubset(['a'], ['b','a']) sera faux, parce que[0 => 'a']
n'est pas à l'intérieur de[0 => 'b', 1 => 'a']
assertEquals
déjà poignées que si les clés ne sont pas dans le même ordre. Je l'ai juste testé.