7
votes

Utilisez le programme DOCTEST et LOGING IN PYTHON

#!/usr/bin/python2.4
import logging
import sys
import doctest
def foo(x):
        """
    >>> foo (0)
    0
        """
        print ("%d" %(x))
        _logger.debug("%d" %(x))
def _test():
        doctest.testmod()
_logger = logging.getLogger()
_logger.setLevel(logging.DEBUG)
_formatter = logging.Formatter('%(message)s')
_handler = logging.StreamHandler(sys.stdout)
_handler.setFormatter(_formatter)
_logger.addHandler(_handler)
_test()
I would like to use logger module for all of my print statements.  I have looked at the first 50 top google links for this, and they seem to agree that doctest uses it's own copy of the stdout.
If print is used it works if logger is used it logs to the root console.
Can someone please demonstrate a working example with a code snippet that will allow me to combine.
Note running nose to test doctest will just append the log output at the end of the test, (assuming you set the switches) it does not treat them as a print statement.

0 commentaires

3 Réponses :


1
votes

Je ne suis pas sûr de savoir pourquoi vous voulez faire cela, mais si vous avez vraiment besoin de le faire, vous pouvez définir votre propre sous-classe de doctstrunner code> et remplacer le exécuter Code> Méthode:

#imports left out, code not tested - just to point you in the right direction
class MyDocTestRunner(DocTestRunner):
    def run(self, test, compileflags=None, out=None, clear_globs=True):
        if out is None:
            handler = None
        else:
            handler = StreamHandler(out)
        logger = logging.getLogger() # root logger (say)
        if handler:
            logger.addHandler(handler)
        try:
            DocTestRunner.run(self, test, compileflags, out, clear_globs)
        finally:
            if handler:
                logger.removeHandler(handler)
                handler.close()


2 commentaires

Ok, merci de la réponse que je tente de le mettre en œuvre. Vous êtes d'avis que les développeurs ne mangent pas normalement la doctest / journalisation et utiliseraient un mélange de journalisation (qui est exclu par un Skip Doctest) et utilise uniquement l'impression pour leur vérification de la doctest?


Je l'ai résolu en configurant le nez pour exécuter Doctest qui exclut la journalisation et simplement à l'aide de déclarations d'impression pour tout ce qui doit faire la comparaison de la journalisation. #! / us



0
votes

Une approche simple et générale ressemble à ceci:

LOGGER = logging.getLogger(__name__)
if hasattr(sys.modules['__main__'], '_SpoofOut'):
    LOGGER.setLevel(logging.DEBUG)
    LOGGER.addHandler(logger.addHandler(logging.StreamHandler()))


0 commentaires

3
votes

Dans votre doctest, avant que toute capture de journalisation n'est nécessaire, faites un addhandler (logging.streamhandler (sys.stdout)) sur votre enregistreur.

par exemple , en supposant que enregistreur est votre objet de journalisation: xxx

explication: une fois que le Doctest est en cours d'exécution, Doctest a déjà mis son Spoof en place, donc sys.stdout est maintenant défini sur doctstrunner._fakeout . Si vous créez un Logging.streamhandler pour SYS.STDOUT à ce stade, SYS.STDOUT Pointez-vous sur la spoof de Doctest pour SYS.STDOUT plutôt que le réel SYS.STDOUT.

Ceci La solution a également l'avantage de ne pas dépendre des variables privées internes dans la doctest, telles que _fakeout ou _poofout , au cas où ils changeront à l'avenir.

< em> gotchas : si vous obtenez xxx

vous avez peut-être oublié de Importer SYS .


2 commentaires

>>> importer SYS; logger.addhandler (Logging.streamhandler (sys.stdout)) Si vous devez importer des systèmes SYS uniquement dans les doctestes et que vous voulez une doublure.


Cela a l'avantage supplémentaire que la sortie de l'enregistreur ne s'affiche plus dans la séquence de '.' ' les caractères qui indiquent des tests étant exécutés.