web-dev-qa-db-fra.com

Unittest - Assert un ensemble d'éléments d'une liste sont ou non contenus dans une autre liste

Bonjour, je suis nouveau en programmation et en essayant de faire un test qui vérifie si any les éléments d’une liste d’éléments sont présents dans une autre liste (en utilisant unittest dans Python 2.7).

Par exemple, si j'ai une liste ["chien", "chat", "grenouille] et que le résultat de la méthode testée est [" tigre "," lion "," kangourou "," grenouille], je veux que le test soit effectué. échouer car il contient l'un des éléments de la liste précédente ("grenouille"). Je voudrais aussi que le test me dise quels mots ont les deux listes (c.-à-d. Quels mots ont fait que le test a échoué).

J'ai essayé:

self.assertIn(["cat", "dog"], method("cat dog tiger"))

Le résultat de la méthode est ["chat", "chien", "tigre"] et pourtant le résultat du test est un échec et dit:

AssertionError: ['cat', 'dog'] not found in ['cat', 'dog', 'tiger']

Je veux que ce test revienne bien parce que "chat" et "chien" sont présents dans la deuxième liste. Il semble qu'assertIn ne fasse pas ce que je pensais qu'il ferait (je pensais que c'était pour vérifier si l'un des a est présent dans b).

Et vice versa, assertNotIn passe lorsque je veux que cela échoue. 

Cela fait un moment que je cherche, mais parce que je ne suis pas sûr de ce que je cherche, ce qui le rend difficile à trouver. 

Merci d'avoir lu, j'espère que cela a du sens. 

EDIT: Je suis parti avec la solution de Chris et ça marche comme je veux:

def myComp(list1, list2):
    section = list(set(list1).intersection(list2))

Pour obtenir la liste des mots qui se chevauchent (c.-à-d. Déclenchant l’échec) dans le message d’erreur, j’ai ajouté le code ci-dessous à partir d’ici Comment changer le message dans une assertionError Python? :

try:
    assert(len(section)==0)
except AssertionError as e:
    e.args += ('The following are present in the processed text', 
    section)
    raise

Le résultat est exactement ce que je veux:

AssertionError: ('The following are pressent in the processed text', ['dog', 
'cat'])
4
RubyJane

Vous devriez regarder cette question , alors vous pouvez facilement voir que quelque chose comme:

def myComp(list1, list2):
  section = list(set(list1).intersection(list2))
  return ((len(section)==0), section)

cette fonction retournera un Tuple avec un booléen indiquant un échec ou un succès et la liste des éléments apparaissant dans les deux listes.

si vous voulez vraiment faire cela dans une déclaration d'assertion, vous pouvez simplement utiliser le premier élément de ce tuple ...

1
Chris

Vous pouvez soit parcourir votre liste et assertIn, soit utiliser sets et faire quelque chose comme self.assertTrue(set(a).issuperset(set(b))).

2
Alex

Si vous attendez des valeurs non répétables dans vos séquences, il est peut-être préférable d'utiliser des ensembles, car vous pouvez facilement les vérifier pour tout type de chevauchement.

>>> a, b = {'dog', 'cat'}, {'dog', 'cat', 'wolf', 'crab'}
>>> a & b
set(['dog', 'cat'])
>>> a ^ b
set(['wolf', 'crab'])

Donc, vérifier si a est un sous-ensemble de b serait quelque chose comme ceci:

>>> not bool(a ^ b & a)
True

etc

1
Violet Red
self.assertTrue(any(animal in method("cat dog tiger") for animal in ("cat", "dog")))
0
user2729400