web-dev-qa-db-fra.com

Journalisation dans les tests py.test

Je voudrais mettre quelques instructions de journalisation dans la fonction de test pour examiner certaines variables d'état.

J'ai l'extrait de code suivant:

import pytest,os
import logging

logging.basicConfig(level=logging.DEBUG)
mylogger = logging.getLogger()

#############################################################################

def setup_module(module):
    ''' Setup for the entire module '''
    mylogger.info('Inside Setup')
    # Do the actual setup stuff here
    pass

def setup_function(func):
    ''' Setup for test functions '''
    if func == test_one:
        mylogger.info(' Hurray !!')

def test_one():
    ''' Test One '''
    mylogger.info('Inside Test 1')
    #assert 0 == 1
    pass

def test_two():
    ''' Test Two '''
    mylogger.info('Inside Test 2')
    pass

if __== '__main__':
    mylogger.info(' About to start the tests ')

    pytest.main(args=[os.path.abspath(__file__)])

    mylogger.info(' Done executing the tests ')

J'obtiens la sortie suivante:

[bmaryada-mbp:/Users/bmaryada/dev/platform/main/proto/tests/tpch $]python minitest.py
INFO:root: About to start the tests 
======================================================== test session starts =========================================================
platform darwin -- Python 2.6.2 -- pytest-2.0.0
collected 2 items 

minitest.py ..

====================================================== 2 passed in 0.01 seconds ======================================================
INFO:root: Done executing the tests 

Notez que seuls les messages de journalisation du '__== __main__' le bloc est transmis à la console.

Existe-t-il un moyen de forcer pytest à émettre également une journalisation sur la console à partir des méthodes de test?

60
superselector

Fonctionne pour moi, voici la sortie que j'obtiens: [snip -> l'exemple était incorrect]

Edit: Il semble que vous devez passer le -s option pour py.test afin qu'il ne capture pas stdout. Ici (py.test non installé), il suffisait d'utiliser python pytest.py -s pyt.py.

Pour votre code, il vous suffit de passer -s dans args à main:

 pytest.main(args=['-s', os.path.abspath(__file__)])

Voir la documentation py.test sur capture de sortie .

26
TryPyPy

Depuis la version 3.3, pytest prend en charge la journalisation en direct, ce qui signifie que tous les enregistrements de journal émis dans les tests seront imprimés sur le terminal immédiatement. La fonctionnalité est documentée dans la section Live Logs . La journalisation en direct est désactivée par défaut; pour l'activer, définissez log_cli = 1 dans la configuration pytest.ini1. La journalisation en direct prend en charge l'émission vers le terminal et le fichier; les options pertinentes permettent de personnaliser les enregistrements:

terminal:

  • log_cli_level
  • log_cli_format
  • log_cli_date_format

fichier:

  • log_file
  • log_file_level
  • log_file_format
  • log_file_date_format

Remarque L'indicateur log_cli Ne peut pas être transmis à partir de la ligne de commande et doit être défini dans pytest.ini. Toutes les autres options peuvent être transmises à partir de la ligne de commande ou définies dans le fichier de configuration. Comme indiqué par Kévin Barré dans ce commentaire , la substitution des options ini depuis la ligne de commande peut se faire via l'option -o/--override. Ainsi, au lieu de déclarer log_cli Dans pytest.ini, Vous pouvez simplement appeler:

$ pytest -o log_cli=true ...

Exemples

Fichier de test simple utilisé pour démontrer:

# test_spam.py

import logging

LOGGER = logging.getLogger(__name__)


def test_eggs():
    LOGGER.info('eggs info')
    LOGGER.warning('eggs warning')
    LOGGER.error('eggs error')
    LOGGER.critical('eggs critical')
    assert True

Comme vous pouvez le voir, aucune configuration supplémentaire n'est nécessaire; pytest configurera automatiquement l'enregistreur, en fonction des options spécifiées dans pytest.ini ou transmises depuis la ligne de commande.

Journalisation en direct sur le terminal, INFO niveau, sortie fantaisie

Configuration dans pytest.ini:

[pytest]
log_cli = 1
log_cli_level = INFO
log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
log_cli_date_format=%Y-%m-%d %H:%M:%S

Exécution du test:

$ pytest test_spam.py
=============================== test session starts ================================
platform darwin -- Python 3.6.4, pytest-3.7.0, py-1.5.3, pluggy-0.7.1 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-4673373, inifile: pytest.ini
collected 1 item

test_spam.py::test_eggs
---------------------------------- live log call -----------------------------------
2018-08-01 14:33:20 [    INFO] eggs info (test_spam.py:7)
2018-08-01 14:33:20 [ WARNING] eggs warning (test_spam.py:8)
2018-08-01 14:33:20 [   ERROR] eggs error (test_spam.py:9)
2018-08-01 14:33:20 [CRITICAL] eggs critical (test_spam.py:10)
PASSED                                                                        [100%]

============================= 1 passed in 0.01 seconds =============================

Journalisation en direct sur le terminal et le fichier, uniquement le message et le niveau CRITICAL dans le terminal, sortie fantaisie dans le fichier pytest.log

Configuration dans pytest.ini:

[pytest]
log_cli = 1
log_cli_level = CRITICAL
log_cli_format = %(message)s

log_file = pytest.log
log_file_level = DEBUG
log_file_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
log_file_date_format=%Y-%m-%d %H:%M:%S

Essai:

$ pytest test_spam.py
=============================== test session starts ================================
platform darwin -- Python 3.6.4, pytest-3.7.0, py-1.5.3, pluggy-0.7.1 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-4673373, inifile: pytest.ini
collected 1 item

test_spam.py::test_eggs
---------------------------------- live log call -----------------------------------
eggs critical
PASSED                                                                        [100%]

============================= 1 passed in 0.01 seconds =============================

$ cat pytest.log
2018-08-01 14:38:09 [    INFO] eggs info (test_spam.py:7)
2018-08-01 14:38:09 [ WARNING] eggs warning (test_spam.py:8)
2018-08-01 14:38:09 [   ERROR] eggs error (test_spam.py:9)
2018-08-01 14:38:09 [CRITICAL] eggs critical (test_spam.py:10)

1 Bien que vous puissiez configurer pytest dans setup.cfg Sous la section [tool:pytest], Ne soyez pas tenté de le faire lorsque vous souhaitez fournir un format de journalisation en direct personnalisé. D'autres outils lisant setup.cfg Peuvent traiter des choses comme %(message)s comme une interpolation de chaîne et échouer. Utilisez pytest.ini Pour éviter les erreurs.

52
hoefling