New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add call recorder for testing purposes #14
Comments
This is a super old issue, but still -- wondering if there's a 'recommended' way of testing structlog loggers these days?.. (which isn't entirely clear from docs or issues, hence the question) |
Here's what I'm usually doing in pytest: class LogCapture:
def __init__(self):
self.entries = []
def __call__(self, _, method_name, event_dict):
event_dict['log_level'] = method_name
self.entries.append(event_dict)
raise structlog.DropEvent
@pytest.fixture(scope='function')
def log_output():
return LogCapture()
@pytest.fixture(scope='function', autouse=True)
def configure_structlog(log_output):
structlog.configure(
processors=[log_output]
) and then you can just def test_my_stuff(log_output):
do_something()
assert log_output.entries == [...] |
Honestly that’s pretty much I had in mind but never got around to implement it in a way that it would warrant the inclusion in structlog proper. Lately I've also been kinda lazy and just used caplog/capsys + simples checks to ensure an entry is in there. |
Here's a non-pytest version, in case anyone comes across this and needs it: class LogCapture:
def __init__(self):
self.entries = []
def __call__(self, _, method_name, event_dict):
event_dict['log_level'] = method_name
self.entries.append(event_dict)
raise structlog.DropEvent
@contextmanager
def capture_logs():
cap = LogCapture()
old_processors = structlog.get_config()['processors']
try:
structlog.configure(processors=[cap])
yield cap.entries
finally:
structlog.configure(processors=old_processors) Yield value looks something like: |
@rgalanakis wow I love that approach! Simple yet powerful! I think I wouldn't be opposed to adding that to |
Great and thanks! Do you want a PR or will you add it yourself? |
I would like you to have the implementation credit but it will take a bit more than just the code. |
See hynek#14 (comment) for more context. It needed to go into its own file, rather than `dev`, because it relies on `_config` and `_config` relies on `dev`.
See hynek#14 (comment) for more context. It needed to go into its own file, rather than `dev`, because it relies on `_config` and `_config` relies on `dev`.
See hynek#14 (comment) for more context. It needed to go into its own file, rather than `dev`, because it relies on `_config` and `_config` relies on `dev`.
See hynek#14 (comment) for more context. It needed to go into its own file, rather than `dev`, because it relies on `_config` and `_config` relies on `dev`.
See hynek#14 (comment) for more context. It needed to go into its own file, rather than `dev`, because it relies on `_config` and `_config` relies on `dev`.
* Add capture_logs context manager See #14 (comment) for more context. It needed to go into its own file, rather than `dev`, because it relies on `_config` and `_config` relies on `dev`. * Rename _capture.py to testing.py * Add docstring to testing.LogCapture Co-authored-by: Hynek Schlawack <hs@ox.cx>
Finally fixed by #234! |
Basically a processor that records all calls and allows assertions against it. Needs #10.
The text was updated successfully, but these errors were encountered: