121 votes

Puis-je déboguer avec le débogueur python lorsque j'utilise py.test d'une manière ou d'une autre ?

J'utilise py.test pour tester unitairement mon programme python. Je souhaite déboguer mon code de test avec le débogueur python de la manière normale (c'est-à-dire pdb.set_trace() dans le code) mais je n'arrive pas à le faire fonctionner.

Mettre pdb.set_trace() dans le code ne fonctionne pas (lève IOError : reading from stdin while output is captured). J'ai également essayé d'exécuter py.test avec l'option --pdb mais cela ne semble pas fonctionner si je veux explorer ce qui se passe avant mon assertion. Le programme s'interrompt lorsqu'une assertion échoue, et continuer à partir de cette ligne signifie terminer le programme.

Est-ce que quelqu'un connaît un moyen d'obtenir le débogage, ou est-ce que le débogage et py.test ne sont tout simplement pas faits pour être ensemble ?

185voto

hpk42 Points 3494

C'est très simple : mettez un assert 0 où vous voulez commencer à déboguer votre code et exécuter vos tests :

py.test --pdb 

c'est fait :)

Alternativement, si vous utilisez pytest-2.0.1 ou plus, il y a aussi l'option pytest.set_trace() que vous pouvez placer n'importe où dans votre code de test. Voici les documents . Il prendra soin de désactiver la capture en interne avant de vous envoyer à la ligne de commande du débogueur pdb.

47voto

Jason R. Coombs Points 11130

J'ai découvert que je pouvais lancer py.test avec la capture désactivée, puis utiliser pdb.set_trace() comme d'habitude.

> py.test --capture=no
============================= test session starts ==============================
platform linux2 -- Python 2.5.2 -- pytest-1.3.3
test path 1: project/lib/test/test_facet.py

project/lib/test/test_facet.py ...> /home/jaraco/projects/project/lib/functions.py(158)do_something()
-> code_about_to_run('')
(Pdb)

32voto

La méthode la plus simple consiste à utiliser le mécanisme py.test pour créer des points d'arrêt.

http://pytest.org/latest/usage.html#setting-a-breakpoint-aka-set-trace

import pytest
def test_function():
    ...
    pytest.set_trace()    # invoke PDB debugger and tracing

Ou si vous voulez pytest comme une ligne de conduite, modifiez votre import pdb; pdb.set_trace() en import pytest; pytest.set_trace()

5voto

Peter Lyons Points 47794

Je ne suis pas familier avec py.test, mais pour unittest, vous faites ce qui suit. Peut-être que py.test est similaire :

Dans votre module de test (mytestmodule.py) :

if __name__ == "__main__":
    unittest.main(module="mytestmodule")

Exécutez ensuite le test avec

python -m pdb mytestmodule.py

Vous obtiendrez un shell pdb interactif.

En regardant la documentation, il semble que py.test ait une fonction --pdb option de ligne de commande :

https://docs.pytest.org/en/7.2.x/reference/reference.html#command-line-flags

5voto

GSP Points 63

Similaire à la réponse de Peter Lyon, mais avec le code exact dont vous avez besoin pour pytest, vous pouvez ajouter ce qui suit au bas de votre module pytest (my_test_module.py) :

if __name__ == "__main__":
    pytest.main(["my_test_module.py", "-s"])

Vous pouvez ensuite invoquer le débogueur à partir de la ligne de commande :

pdb3 my_test_module.py

Boom. Vous êtes dans le débogueur et pouvez entrer des commandes de débogage. Cette méthode laisse votre code de test sans appels set_trace() et s'exécutera dans pytest "normalement".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X