Search code examples
pythonpytestself

Why pytest calls a duplicate method


why does this happen? duplicate call because I added "self.log"

code

import logging, logging.handlers
class TestCase:

    def setup_method(self,test_method):
            self.log = logging.getLogger('test')
            self.log.addHandler( logging.StreamHandler())

    def test_one(self):
            log = self.log
            log.info('one')
    def test_two(self):
            log = self.log
            log.info('two')

console out

$pytest -s
=========================================== test session starts ===========================================
platform darwin -- Python 3.6.2, pytest-3.3.1, py-1.5.2, pluggy-0.6.0
rootdir: /Users/taeun/dev/workspace/test/pytest-test/tests, inifile:
collected 2 items

test_one.py one
.two
two
.                                                                                      [100%]

anyone help me?


Solution

  • That's because you are adding a StreamHandler to your logger in the setup_method, which will be called once for each test run. What happens if you run both tests:

    1. setup_method is called, one instance of StreamHandler is added to the logger
    2. test_one runs, the logger has one handler that send the message one to stdout
    3. setup_method is called for the second time, adding another instance of StreamHandler to the logger handlers
    4. test_two runs, but now the logger has two handlers, both sending the message two to stdout

    To overcome this, you can either clean up handlers in the setup_method to ensure you have one StreamHandler on each test run:

    class TestCase:
    
        def setup_method(self):
            self.log = logging.getLogger('test')
            self.log.handlers = [h for h in self.log.handlers
                                 if not isinstance(h, logging.StreamHandler)]
            self.log.addHandler(logging.StreamHandler())
    
            ...
    

    or you declare the logger configuration as a one-time operation (a much cleaner solution if you ask me):

    class TestCase:
    
        @classmethod
        def setup_class(cls):
            logging.getLogger('test').addHandler(logging.StreamHandler())
    
        def setup_method(self,test_method):
            self.log = logging.getLogger('test')
    
        ...