I have the following test class for pytest:
class TestConnection(AsyncTestCase):
'''Integration test'''
@gen_test
def test_connecting_to_server(self):
'''Connecting to the TCPserver'''
client = server = None
try:
sock, port = bind_unused_port()
with NullContext():
server = EchoServer()
server.add_socket(sock)
client = IOStream(socket.socket())
#### HERE I WANT TO HAVE THE caplog FIXTURE
with ExpectLog(app_log, '.*decode.*'):
yield client.connect(('localhost', port))
yield client.write(b'hello\n')
# yield client.read_until(b'\n')
yield gen.moment
assert False
finally:
if server is not None:
server.stop()
if client is not None:
client.close()
Within this class apparently ExpectLog is not working so after a day of digging around in pytest's documentation I found that there is this caplog fixture that you can have inserted in you methods in order to access the captured logs. It seems to work if I have a test function to which I add the caplog argument but how do I make the caplog fixture available within the methods of a test class like the one above?
Fixtures and their visibility are a bit odd in pytest. They don't require importing, but if you defined them in a test_*. py file, they'll only be available in that file. You can however put them in a (project- or subfolder-wide) conftest.py to use them in multiple files.
To access the fixture function, the tests have to mention the fixture name as input parameter. Pytest while the test is getting executed, will see the fixture name as input parameter. It then executes the fixture function and the returned value is stored to the input parameter, which can be used by the test.
Parametrized tests The above decorator is a very powerful functionality, it permits to call a test function multiple times, changing the parameters input at each iteration.
“Requesting” fixtures At a basic level, test functions request fixtures they require by declaring them as arguments. When pytest goes to run a test, it looks at the parameters in that test function's signature, and then searches for fixtures that have the same names as those parameters.
Although you can't pass fixtures as parameters to unittest
test methods, you can inject them as instance attributes. Example:
# spam.py
import logging
def eggs():
logging.getLogger().info('bacon')
Test for spam.eggs()
:
# test_spam.py
import logging
import unittest
import pytest
import spam
class SpamTest(unittest.TestCase):
@pytest.fixture(autouse=True)
def inject_fixtures(self, caplog):
self._caplog = caplog
def test_eggs(self):
with self._caplog.at_level(logging.INFO):
spam.eggs()
assert self._caplog.records[0].message == 'bacon'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With