Skip to content
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

Sketch: new testing API #432

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft

Conversation

itamarst
Copy link
Owner

@itamarst itamarst commented Aug 11, 2019

The current testing API:

  1. Duplicate parts of eliot.parse.
  2. Changes Logger global state, which means it's hard to do things like additionally logging all messages via py.test plugin.

New design:

  1. Rely on eliot.parse for validation of messages (will likely port some of the utility methods from eliot.testing.)
  2. Messages are captured via a destination, so it's possible to add other destinations as well.
  3. Downside: tracebacks on errors may be less nice, not sure yet.

Any thoughts? @exarkun @thedrow @jonathanj

@itamarst itamarst changed the title New testing API Sketch: new testing API Aug 11, 2019
Copy link

@thedrow thedrow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just neatpicking.
This looks good otherwise.


def class_fqpn(typ):
"""Convert a class to it's fully-qualified name."""
return "%s.%s" % (typ.__module__, typ.__name__)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you just use __qualname__?
It's available since Python 3.3.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python 2.7 is still supported.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not anymore! But when that code was written, it was supported.

lambda typ: "%s.%s" % (typ.__module__, typ.__name__),
"The exception type's FQPN.",
),
Field(EXCEPTION_FIELD, class_fqpn, "The exception type's FQPN."),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If using __qualname__ is possible you can simply use operator.attrgetter("__qualname__") instead of class_fpqn.

@exarkun
Copy link
Collaborator

exarkun commented Aug 12, 2019

Any thoughts? @exarkun @thedrow @jonathanj

Can you write some developer-facing prose/howto docs for this feature? I will read and comment on those. Skimming the current diff, it's not obvious to me how this is meant to be used. I'd rather comment on UX of the API than implementation details. :)

@itamarst
Copy link
Owner Author

itamarst commented Aug 12, 2019

I'll write some docs when I have time, yeah.

But quick version is:

class MyTests(unittest.TestCase):
    def test_mything(self):
        logs = logs_for_pyunit(self)  # start capturing logs
        do_my_thing()  # run normal test code

        # Ok now you can make assertions about logs:
        # 1. I expect a ZeroDivisionError to be logged.
        assert len(logs.remove_expected_tracebacks(ZeroDivisionError)) == 1
        # 2. I expect a my_action action:
        assert logs.messages[0]["action_type"] == "my_action"
        # Or something like
        [action] = logs.parse()
        # Now I have a eliot.parse.WrittenAction to play with

@itamarst
Copy link
Owner Author

If you have a custom JSON encoding class:

def test_mytest(self):
    # Check that encodes using custom JSON encoder (and then decodes with default json.loads):
    logs = logs_for_pyunit(self, encode=CustomEncoder().encode)
    # ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants