Skip to content

gh-127221: Add colour to unittest output - #127223

Merged
hugovk merged 7 commits into
python:mainfrom
hugovk:3.14-unittest-colour
Dec 5, 2024
Merged

gh-127221: Add colour to unittest output#127223
hugovk merged 7 commits into
python:mainfrom
hugovk:3.14-unittest-colour

Conversation

@hugovk

@hugovkhugovk commented Nov 24, 2024

Copy link
Copy Markdown
Member

Use the existing _colorize module already used for tracebacks and doctest so output can be controlled with the PYTHON_COLORS, NO_COLOR and FORCE_COLOR environment variables.

This PR does a couple of things to add colour:

  • Enable colour for tracebacks by passing in colorize to msgLines = list(tb_e.format(colorize=can_colorize()))
  • Add colour for pass/fail/errors, using pytest as a guide
  • Plus some unrelated tidy-up (use more specific test methods, new-style objects, underscore variables)

Tested with some small demo scripts:

No tests ran

run-unittests-none.py
importunittestif__name__=="__main__":
unittest.main()
Before After pytest
imageimageimage

Passed

run-unittests-pass.py
Mode Before After pytest
Regular imageimageimage
Verbose imageimageimage

Failing

run-unittests.py
importunittestclassTestThings(unittest.TestCase):
deftest_pass(self):
self.assertTrue(True)
deftest_fail(self):
self.assertTrue(False)
deftest_error(self):
raiseException("Manually raised exception")
deftest_pass2(self):
self.assertEqual(1, 1)
@unittest.skip("demonstrating skipping")deftest_skip(self):
self.fail("shouldn't happen")
classExpectedFailureTestCase(unittest.TestCase):
@unittest.expectedFailuredeftest_fail(self):
self.assertEqual(1, 0, "broken")
@unittest.expectedFailuredeftest_pass(self):
self.assertEqual(1, 1, "not broken")
if__name__=="__main__":
unittest.main()
Mode Before After pytest
Regular imageimageimage
Verbose imageimageimage

Subtests

run-unittests-subtests.py
importunittestclassDoSubTest(unittest.TestCase):
deftest_subtest(self):
"""Test with subtest"""foriinrange(0, 4):
withself.subTest(i=i):
ifi==2:
raiseException("Manually raised exception")
self.assertEqual(i%2, 0)
if__name__=="__main__":
unittest.main()
Mode Before After pytest
Regular imageimageimage
Verbose imageimageimage

📚 Documentation preview 📚: https://cpython-previews--127223.org.readthedocs.build/

@hugovkhugovk added type-feature A feature request or enhancement stdlib Standard Library Python modules in the Lib/ directory labels Nov 24, 2024
@hugovkhugovk changed the title Add colour to unittest outputgh-127221: Add colour to unittest outputNov 24, 2024
@nineteendo

Copy link
Copy Markdown
Contributor

Looks good, I see you're taking some inspiration from pytest, but I had to zoom in all the way to be able to read the text. :)

@hugovk

Copy link
Copy Markdown
MemberAuthor

You can click the images to open them full size.

@nineteendo

nineteendo commented Nov 24, 2024

Copy link
Copy Markdown
Contributor

Well, I wanted to compare the images so I had to zoom in to see the difference. Maybe we could only show the comparison between pytest? The uncoloured images don't add much value.

Comment threadLib/test/test_unittest/support.py Outdated
Comment threadLib/test/test_unittest/test_discovery.py Outdated

@AlexWaygoodAlexWaygood left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is great!! With the coloured tracebacks as well, though, I sort-of feel like there might be a bit too much colour now when tests fail. It feels slightly overwhelming!

What about making only the "ERROR"/"FAIL"/"UNEXPECTED SUCCESS" lines coloured red, and not the ======= line above or the ------- below?

@hugovk
hugovkforce-pushed the 3.14-unittest-colour branch from e18da3e to d01272fCompareNovember 24, 2024 16:32
self.assertTrue(test.doCleanups())
self.assertEqual(cleanups, [(2, (), {}), (1, (1, 2, 3), dict(four='hello', five='goodbye'))])

@force_not_colorized

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we have to apply this decorator to so many methods that I almost wonder if it's worth having a custom metaclass that automatically adds it to each method on the class... or we could not use the @force_not_colorized decorator, and instead duplicate the logic in setUp and tearDown methods on the TestCleanup class here.

Neither feels ideal; it might be that what you have now is in fact best!

@hugovk

Copy link
Copy Markdown
MemberAuthor

This is great!! With the coloured tracebacks as well, though, I sort-of feel like there might be a bit too much colour now when tests fail. It feels slightly overwhelming!

What about making only the "ERROR"/"FAIL"/"UNEXPECTED SUCCESS" lines coloured red, and not the ======= line above or the ------- below?

Thanks! Here's without coloured separators:

image

And verbose:

image

What do you think?

Also these demo scripts are a bit contrived; hopefully most of the time, most of your tests pass and just one or two fail. But then again, sometimes a lot do fail!

@AlexWaygood

Copy link
Copy Markdown
Member

Nice, that looks great to me now!

@nineteendo

nineteendo commented Nov 24, 2024

Copy link
Copy Markdown
Contributor

How about swapping the rows and columns in the table? It makes the text better readable:

show table
ModeRegularVerbose
Beforeimageimage
Afterimageimage
pytestimageimage

@AlexWaygood

Copy link
Copy Markdown
Member

How about swapping the rows and columns in the table? It makes the text better readable:

To be clear @nineteendo, this is a comment on the table in Hugo's PR description rather than the code he's changing in this PR, correct?

@nineteendo

Copy link
Copy Markdown
Contributor

Correct, with 3 images on the same row I can't read the text without zooming in.

@AlexWaygood

Copy link
Copy Markdown
Member

I see.

@hugovk, do you think we should add a link to the using-on-controlling-color somewhere in the unittest docs? I see we didn't when we added color support to doctest, but maybe we should have done

@hugovk

Copy link
Copy Markdown
MemberAuthor

@hugovk, do you think we should add a link to the using-on-controlling-color somewhere in the unittest docs? I see we didn't when we added color support to doctest, but maybe we should have done

Yeah, good idea. Something like 5a1de7c?

Let's also add it to doctest and traceback.

@AlexWaygoodAlexWaygood left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice!

Comment threadDoc/library/unittest.rst Outdated

@sobolevnsobolevn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! I like the idea. But, I personally feel like it is still a bit too colorful. Right now almost nothing is white.

One more idea: can you please test this with the white theme as well?

@hugovk

Copy link
Copy Markdown
MemberAuthor

Thank you! I like the idea. But, I personally feel like it is still a bit too colorful. Right now almost nothing is white.

Almost nothing is white because these demo scripts are intentionally crafted to generate lots of failures :) It's very similar to pytest.

One more idea: can you please test this with the white theme as well?

Sure:

unittest pytest
imageimage
imageimage
imageimage
imageimage
imageimage

Note I've not adjusted my local colours for this light theme. If I was using it normally, I may have adjusted it already for pytest.

Comment threadMisc/NEWS.d/next/Library/2024-11-23-00-17-29.gh-issue-127221.OSXdFE.rst Outdated
Co-authored-by: Kirill Podoprigora <kirill.bast9@mail.ru>
@hugovk
hugovk merged commit 23f2e8f into python:mainDec 5, 2024
@hugovk
hugovk deleted the 3.14-unittest-colour branch December 5, 2024 19:10
srinivasreddy pushed a commit to srinivasreddy/cpython that referenced this pull request Jan 8, 2025
Co-authored-by: Kirill Podoprigora <kirill.bast9@mail.ru>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@hugovk@nineteendo@AlexWaygood@sobolevn@Eclips4