GithubHelp home page GithubHelp logo

etianen / logot Goto Github PK

View Code? Open in Web Editor NEW
91.0 3.0 1.0 847 KB

Test whether your code is logging correctly ๐Ÿชต

Home Page: https://logot.readthedocs.io

License: MIT License

Python 100.00%
testing logging python pytest-plugin

logot's Issues

`logot` only works with the default `loguru` logger?

Thanks for your work.

Is it possible to configure loguru or does logot only work with a pre-configured default logger?

# test_logger.py
import sys
from typing import Callable

import pytest
from logot import Logot, logged
from logot.loguru import LoguruCapturer
from loguru import logger
from rich.logging import RichHandler


@pytest.fixture(scope="session")
def logot_capturer() -> Callable[[], LoguruCapturer]:
    return LoguruCapturer


def test_capture(logot: Logot):
    """
    Works
    """
    # Log an error message with the default logger
    logger.info("foo bar")
    logot.assert_logged(logged.info("foo bar"))


def test_capture_setup_logger(logot: Logot):
    """
    Does not work
    """
    # Remove all handlers added so far, including the default one.
    logger.remove()
    # Console handler
    logger.add(sink=sys.stderr, level="DEBUG", format="{message}")

    # Log an error message
    logger.info("foo bar")
    logot.assert_logged(logged.info("foo bar"))


def test_capture_setup_logger_rich(logot: Logot):
    """
    Does not work
    """
    # Remove all handlers added so far, including the default one.
    logger.remove()
    # Console handler with rich formatting
    logger.add(
        sink=RichHandler(
            log_time_format="[%X]",
            rich_tracebacks=True,
            tracebacks_show_locals=True,
        ),
        level="DEBUG",
        format="{message}",
    )

    # Log an error message
    logger.info("foo bar")
    logot.assert_logged(logged.info("foo bar"))

Errors:

$ test_capture_setup_logger 
AssertionError: Not logged:
[INFO] foo bar

Captured stderr call:
foo bar

$ test_capture_setup_logger_rich
AssertionError: Not logged:
[INFO] foo bar

Captured stderr call:
[01:02:03] INFO     foo bar                                    test_logger.py:42

Loguru docs:

You should remove() it first if you plan to add() another handler logging messages to the console, otherwise you may end up with duplicated logs.

Allow matching on `exc_info`

This would allow asserting that an exception had been logged. Supporting bool | BaseException for the match would be ideal.

  • False - No exception
  • True - Any exceptiom
  • BaseException - Equality
  • None - Anything

A logged.exception() helper would complete the feature.

Support ELLIPSIS marker

With using doctest you can use ... to mean regex-like .* catchall.
When converting to logot I stumbled upon AssertionError: Not logged: until realizing I had ... inside the expected output.

Support `trio`

We can support trio by allowing the async waiter implementation to be customized in the Logot constructor.

Overload the `*` operator for `Logged`

This can be used to create repetitions of log patterns.

  • Use this in the why test logging example like this:

    from logot import Logot, logged
    
    def test_poll_daemon(logot: Logot) -> None:
        app.start_poll()
        logot.wait_for(
            (logged.info("Poll started")) >> logged.info("Poll finished")) * 3
        )
  • Link to the log pattern matching docs from this example.

  • Implement with _from_compose to correctly flatten _OrderedAllLogged.

Only import `asyncio` if actually used

It's a big heavy framework we don't always need to import. Since we're only importing 3rd-party libs when actually used, it would be ideal to treat heavyweight stdlib modules the same.

Since asyncio is the default async waiter, probably a lazy import is best to keep the default async waiter zero-config.

Support `loguru`-style message matching

Originally intended as be part of #28, this has been moved to a separate issue following discussion with loguru devs in Delgan/loguru#1072. ๐Ÿ‘

Proposed API

Support .format()-style placeholders like this:

from logot.contrib.loguru import logged

logot.wait_for(logged.info("Hello {}"))

Support matching structured data like this (requires #25):

logot.wait_for(
    logged.bind(foo="bar").info("Hello {}")
)

Implementation

Parsing of the format-style placeholders should be nice and easy using string.Formatter.parse(). Probably easier than the normal %-style placeholder parsing!

Support `loguru` log capture

Supporting a basic loguru integration would be very easy by providing a context manager via a helper func using their LogHandler integration.

Alternatively, a Logot subclass called Logurot would be cheese and fun. That would allow the pytest plugin to provide a logurot fixture too (if loguru is installed).

Only import `logging` if actually used

Although less heavyweight than asyncio (see #81), logging is still quite chunky and part of proving our support for any logging framework (see #28) is not giving special preference to logging.

Support doctest

I try to use doctest only in my code (with occasional unittest.DoctestRunner) and it's always a hassle to capture log output, because doctest clones the logger instances transparently (or something).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.