Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 5 additions & 14 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,22 @@ jobs:
- "3.10"
- "3.11"
- "3.12"

- "3.13"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install
run: |
set -xe
python -m pip install --editable .
run: pip install --editable . --config-settings editable_mode=strict

- name: Run tests for ${{ matrix.python-version }}
run: python -m pytest
run: pytest

- name: Run mypy checks for ${{ matrix.python-version }}
run: |
python -m pip install mypy
python -m mypy pytest_structlog

- name: Run mypy install checks for ${{ matrix.python-version }}
run: |
# This checks that things like the py.typed bits work
cd tests
python -m pip install ..
python -m mypy .
pip install mypy
mypy pytest_structlog

- uses: jakebailey/pyright-action@v2
with:
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ Then your test suite might use assertions such as shown below:

``` python
# test_your_lib.py
from pytest_structlog import StructuredLogCapture

from your_lib import spline_reticulator
import pytest_structlog

def test_spline_reticulator(log: pytest_structlog.StructuredLogCapture):

def test_spline_reticulator(log: StructuredLogCapture):
assert len(log.events) == 0
spline_reticulator()
assert len(log.events) == 5
Expand Down Expand Up @@ -99,6 +101,9 @@ def test_spline_reticulator(log: pytest_structlog.StructuredLogCapture):
{"event": "processing", "level": "debug", "spline": 2},
{"event": "processing", "level": "debug", "spline": 0},
] <= log.events

# count of events
assert log.count("processing") == 3
```

## Advanced configuration
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "pytest-structlog"
version = "1.1"
version = "1.2"
description = "Structured logging assertions"
readme = "README.md"
classifiers = [
Expand Down Expand Up @@ -44,3 +44,4 @@ warn_unused_ignores = true
warn_return_any = true
warn_unreachable = true
strict_equality = true
exclude = "tests"
10 changes: 10 additions & 0 deletions pytest_structlog/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ def has(self, message: str, **context: Any) -> bool:
context["event"] = message
return any(is_submap(context, e) for e in self.events)

def count(self, message: str, **context: Any) -> int:
"""Returns the number of messages logged, with optional
subcontext. Usage in test code would be with an assertion, e.g.:

assert log.count("foo") == 2
assert log.count("bar", k1="v1", k2="v2") == 1
"""
context["event"] = message
return sum(is_submap(context, e) for e in self.events)

def log(self, level: Union[int, str], event: str, **kw: Any) -> dict[str, Any]:
"""Create log event to assert against."""
return dict(level=level_to_name(level), event=event, **kw)
Expand Down
13 changes: 13 additions & 0 deletions tests/test_issue39.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import structlog

from pytest_structlog import StructuredLogCapture

logger = structlog.get_logger()


def test_count(log: StructuredLogCapture):
for i in range(3):
logger.info("hello iteration", it=i)
assert log.count("hello iteration") == 3
assert log.count("hello iteration", it=1) == 1
assert log.count("hello iteration", k=1) == 0