Skip to content

Conversation

@hugovk
Copy link
Member

@hugovkhugovk commented Nov 24, 2024

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
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
MemberAuthor

You can click the images to open them full size.

@nineteendo
Copy link
Contributor

nineteendo commented Nov 24, 2024

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.

Copy link
Member

@AlexWaygoodAlexWaygood left a comment

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?

@hugovkhugovkforce-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
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
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
Member

Nice, that looks great to me now!

@nineteendo
Copy link
Contributor

nineteendo commented Nov 24, 2024

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
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
Contributor

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

@AlexWaygood
Copy link
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
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.

Copy link
Member

@AlexWaygoodAlexWaygood left a comment

Choose a reason for hiding this comment

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

Nice!

Copy link
Member

@sobolevnsobolevn left a comment

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
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.

Co-authored-by: Kirill Podoprigora <kirill.bast9@mail.ru>
@hugovkhugovk merged commit 23f2e8f into python:mainDec 5, 2024
@hugovkhugovk 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