2009-07-23 5 views
1

Le module unittest de Python signale-t-il toujours les erreurs en stricte correspondance avec l'ordre d'exécution des lignes dans le code testé? Les erreurs créent-elles la possibilité de changements inattendus dans les variables du code? J'ai été déconcerté par une KeyError rapportée par unittest. La ligne elle-même semble correcte. Sur la dernière ligne avant l'arrêt de l'exécution, débogage des impressions de la clé demandée et le dictionnaire a montré que la clé était dans le dictionnaire. La clé référencée dans KeyError était une clé différente, mais cela semblait aussi être dans le dictionnaire. J'ai inséré une variable compteur dans la boucle externe pour imprimer le nombre d'itérations externes juste avant la ligne d'erreur (à l'intérieur d'une boucle interne), et celles-ci ne sont pas sorties dans la séquence attendue. Ils sortent quelque chose comme 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 2, 2, 2 - quand je m'attendrais à quelque chose comme 0, 0, 0, 1, 1, 1, 2, 2, 2. Et les impressions de débogage des données internes montrent des changements inattendus d'une boucle à l'autre.Est-ce que Python unittest signale des erreurs immédiatement?

code (avec de nombreuses lignes de débogage):

def onSave(screen_data): 
    counter = 0 
    for table, flds_dct in self.target_tables.items(): 
     print 'TABLE %s' % table 
     print 'FIELDS: %s' % flds_dct['fields'] 
     tbl_screen_data = {} 
     for fld in flds_dct['fields']: 
      print 'LOOP TOP' 
      print 'FIELD: %' % fld 
      print 'SCREEN DATA: %s' % screen_data 
      print 'COUNTER: %s' % counter 
      print 'SCREEN DATA OUTPUT: %s' % screen_data[fld] 
      tbl_screen_data[fld] = screen_data[fld] 
      print 'LOOP BOTTOM' 
     self.tables[table].addEntry(tbl_screen_data) 
     counter =+ 1 
     print 'OUTER LOOP BOTTOM' 

Juste avant l'erreur, cette sortie:

TABLE: questions 
FIELDS: ['whatIsYourQuest', 'whatIsYourName', 'whatIsTheAirSpeedOfSwallow'] 
LOOP TOP 
FIELD: whatIsYourQuest 
SCREEN DATA: 
{'whatIsYourQuest': 'grail', 
'whatIsYourName': 'arthur', 
'whatIsYourFavouriteColour': 'blue', 
'whatIsTheAirSpeedOfSwallow': 'african or european?', 
'whatIsCapitalOfAssyria': 'Nineveh'} 
    COUNTER: 1 
    SCREEN DATA OUTPUT: grail 
    LOOP BOTTOM 
    OUTER LOOP BOTTOM 

Mais l'exécution arrête et je reçois ce message d'erreur:

line 100, in writeData 
    print 'SCREEN DATA OUTPUT: %s screen_data[fld] 
KeyError: 'whatIsCapitalOfAssyria' 

Mais l'erreur est attribuée à une ligne qui a déjà imprimé sa sortie et arrête l'exécution après t La sortie de plusieurs lignes après la ligne avec l'erreur.

Comme je l'ai mentionné ci-dessus, un débogage supplémentaire montre que le contenu de screen_data est modifié au cours des itérations de la boucle. Fondamentalement, le dictionnaire transmis n'a pas de clé 'whatIsCapitalOfAssyria'.

L'absence de cette clé était la cause de l'erreur. À un certain point, le code a demandé au dictionnaire screen_data 'whatIsCapitalOfAssyria', auquel il n'a pas pu répondre, et donc, bien sûr, il a été jeté du Pont de la Mort, err, échoué. MAIS il était difficile de voir que lorsque l'objet screen_data produit dans les lignes de débogage a a la clé; et la condition d'erreur signalée n'est pas levée avant l'exécution de beaucoup plus de lignes, ce qui rend confus l'inspection des valeurs locales à l'erreur.

Alors comment unittest gère-t-il les erreurs de code? Qu'est-ce que je fais mal ici? Comment dois-je l'utiliser pour éviter ce genre de chose?

EDIT: Il peut être utile si j'ai ajouté que la méthode testée déclenche des appels sur un certain nombre d'autres méthodes, ce qui déclenche les appels eux-mêmes. Je pense que tout cela est raisonnablement bien testé, mais peut-être que le nombre d'appels interconnectés est important.

+1

Si vous ne l'avez pas déjà fait, supprimez tous les fichiers .pyc et .pyo dans les répertoires à partir desquels vous exécutez ce code, puis réessayez. Parfois, lorsque je reçois des résultats inexplicables comme celui-ci, un fichier bytecode qui n'est pas synchronisé avec la source est la cause (il est vrai que c'est plutôt rare). –

Répondre

1

Je pense que vous voyez l'erreur à la branche NEXT de votre boucle for, par rapport à celle avec laquelle vous voyez toute la sortie - essayez de changer les instructions print en print>>stderr, afin que le tampon et la suppression possible de sortie n'est pas un risque.

+0

Je vais essayer. Franchement, même si je voudrais comprendre cela, le problème immédiat est résolu, il pourrait donc s'écouler un certain temps avant que je dise comment cela a fonctionné. – chernevik

Questions connexes