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

Improve test collection and output #160

Merged
merged 26 commits into from
Dec 8, 2023

Conversation

edoardob90
Copy link
Member

@edoardob90 edoardob90 commented Nov 23, 2023

Changes how the test report is collected and the output message printed to the user.

Beware that the format_assertion_error function might not handle all cases. By default, if no special case is found with the assertion, the message is printed as-is, converted to HTML.

Lines 124-126 of testsuite.py will be irrelevant when the PR on async testing is merged, but I needed them for testing purposes.

@edoardob90
Copy link
Member Author

@despadam It's a small modification of your implementation. Comments/suggestions are welcome!

@baffelli
Copy link
Member

Thanks @edoardob90 🙏👍 I will review it tomorrow

@edoardob90
Copy link
Member Author

edoardob90 commented Nov 23, 2023

Thanks @edoardob90 🙏👍 I will review it tomorrow

Thanks. Have a look and try it out, there might be some edge cases I did not handle. Also: we're collecting the full traceback with your TestResult class, but maybe it's not necessary.

We can then change the draft status and do some cleanup/rewriting some bits in a better way.

@baffelli
Copy link
Member

Thanks @edoardob90 🙏👍 I will review it tomorrow

Thanks. Have a look and try it out, there might be some edge cases I did not handle. Also: we're collecting the full traceback with your TestResult class, but maybe it's not necessary.

We can then change the draft status and do some cleanup/rewriting some bits in a better way.

It's a great starting point and we did good progress today. We can merge it soon and later change as needed. it is great to have structured information on test failure and not having to extract it from the very verbose stdout

success=False,
stdout=None,
stderr=None,
exception=traceback.format_exception_only(call.excinfo.value),
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer that the formatting happens at the time of construction of the test output.
We could store the excinfo here and call the method later.

Copy link
Member

@baffelli baffelli left a comment

Choose a reason for hiding this comment

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

Excellent work @edoardob90. I have a few ideas, with your agreement I will just create a new commit with those.

stdout: str | None
stderr: str | None
exception: List[str] | None
traceback: List[str] | None
Copy link
Member

Choose a reason for hiding this comment

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

I would add a status variable instead of success. This could have the following states:

  • Passed
  • Failed
  • Syntax error
    In this way we can also report syntax errors or any other error that happens during the test collection phase but before the test is run.

tutorial/tests/testsuite_helpers.py Outdated Show resolved Hide resolved
@edoardob90 edoardob90 changed the title Improved error collection and output Improve test collection and output Nov 24, 2023
@baffelli
Copy link
Member

Following changes should be added:

  • Suppress all Ipython messages and replace them with the Ipytest output
  • Handle syntax error, test collection failure and test results more uniformly through a data class
  • Handle output with a single function

@baffelli
Copy link
Member

Following changes should be added:

  • Suppress all Ipython messages and replace them with the Ipytest output
  • Handle syntax error, test collection failure and test results more uniformly through a data class
  • Handle output with a single function

A lot of this was achieved today in a monster refactor with @edoardob90 🔥. Missing:

  • a single function to format the output

@baffelli
Copy link
Member

Added the following:

  • Found a cleaner way to suppress tracebacks
  • Fixed the missing widget output

@edoardob90
Copy link
Member Author

Tidbits from the last commit:

  • Everything, except bundling the output, happens in the TestMagic class
  • The final output (test results + solution code) is delegated to the helper class TestResultOutput (perhaps to rename)
  • Only one function to format an exception: format_error from the testsuite_helpers.py module

@baffelli
Copy link
Member

Great work today @edoardob90 🔥. Let's merge this soon and get back to the course materials

@edoardob90
Copy link
Member Author

edoardob90 commented Nov 30, 2023

In the last commit:

  • ResultCollector now catches an exception raised when running a test. It creates a TestCaseResult with outcome=TestOutcome.TEST_ERROR. This has to be handled somehow in the output, and it's matched by the case IPytestOutcome.FINISHED because the tests indeed finished running.
  • If the call phase runs with no exceptions, then we are able to capture stdout or stderr. They are formatted in two collapsible sections, with each stdout/err in a separate box.

It might not be necessary to capture the outputs/errors from all the tests, but we cannot know in advance if some output is tied to the input of the solution function. For example, in this case, it's redundant:

def solution_power2(x: int) -> int:
    print("name")
    return x * 2

because the same string will be printed every time. While in the following case it's not:

def solution_power2(x: int) -> int:
    print("x is", x)
    return x * 2

I don't see another way of dealing with this.

@baffelli
Copy link
Member

Thanks @edoardob90 , we did good progress today! Now missing:

@baffelli
Copy link
Member

baffelli commented Dec 6, 2023

Shall we merge this?

@edoardob90 edoardob90 marked this pull request as ready for review December 6, 2023 15:34
baffelli and others added 2 commits December 7, 2023 16:51
* Added testing of async functions.

* Add 'async' keyword to %%ipytest

---------

Co-authored-by: Edoardo Baldi <edoardob90@gmail.com>
@edoardob90
Copy link
Member Author

edoardob90 commented Dec 8, 2023

There's still one TODO left: catching if an exception is raised in the solution function. Check out #165 .

Right now, if that happens, the test outcome is set to TEST_ERROR, while it should be FAILED.

@edoardob90
Copy link
Member Author

Great! 🚀 Thanks @baffelli @despadam 👏🏻

@edoardob90 edoardob90 merged commit 4dc3a7e into main Dec 8, 2023
1 check passed
@edoardob90 edoardob90 deleted the fix/improve-test-collection-and-output branch December 8, 2023 16:10
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.

Fix formatting of Pytest error message
3 participants