CleanCut / green

Green is a clean, colorful, fast python test runner.
MIT License
785 stars 75 forks source link

Module and class headings are to late on stdout #224

Closed buhtz closed 4 years ago

buhtz commented 4 years ago

green

I would name line #4 the module heading and line #5 the class heading

The output from line 2 & 3 comes from the setUpClass() method.

I would assume that the heading for module is print to stdout before setUpModul() is called and the heading for the class before the call of setUpClass().

What do you think?

CleanCut commented 4 years ago

No, the module and class are extracted from the test. Whenever a test has a new module and/or class, the appropriate headings are printed immediately before the test line.

By default, stdout and stderr should be captured and reported later in a section that tells you exactly where they came from. Did you disable that feature with -a or --allow-stdout?

buhtz commented 4 years ago

Sorry I should have create a minimal working example from the beginning of that issue. Here it is

Clipboard01

That is test_green.py


import unittest

class TestGreen(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print('create temporary profile files')

    @classmethod
    def tearDownClass(cls):
        print('remove temporary profile files')

    def test_foobar(self):
        self.assertTrue(True)

if __name__ == '__main__':
    unittest.main()

And this is the output (edited manually by me) as I would expect it


green --processes 1 -vvv tests/test_green.py
Green 3.1.4, Coverage 5.1, Python 3.7.3

tests.test_green
  TestGreen
create temporary profile files
    test_foobar
.   test_foobar
remove temporary profile files

Ran 1 test in 0.118s using 1 process

OK (passes=1)

btw: I do not understand why test_foobar appears two times in that output - one in white-bold and one in green-bold (color depends on my terminator theme).

CleanCut commented 4 years ago

Ah, thank you! The fact that this output is not getting captured is a bug. I'll look into that.

btw: I do not understand why test_foobar appears two times in that output - one in white-bold and one in green-bold (color depends on my terminator theme).

The test line is printed twice (first white before it is run, then overwritten in the result color after it is run) for two reasons:

  1. In case there is a catastrophic crash that brings down Green during a test, the test itself will have already been output (in white)
  2. If a test takes a very long time (minutes, for example) it is very convenient for the test to have already been printed before it has been started.

Unless people interactively watch slow tests, they rarely notice the white version being printed.

CleanCut commented 4 years ago

I finished my investigation. Green has never supported capturing output from module/class setups or teardowns, despite me thinking I had implemented that. Though I would like to add this as a feature, it is extremely difficult and I am not planning on taking it on. If someone would like to give it a try, I'd be happy to collaborate on a pull request. The place to start is green/suite.py in GreenTestSuite.run.

The workaround is: Don't write to stdout/stderr in class/module setups or teardowns.

I updated the documentation for -a/--allow-stdout to point out that we only capture output for tests, not setups and teardowns.

buhtz commented 4 years ago

Thanks a lot for your fast reactions and good explanations.

CleanCut commented 4 years ago

No problem! Sorry I couldn't provide a more satisfying response in this instance. This is the drawback of hitching Green to unittest -- having to deal with it's internal implementation. On the other hand, there's no barrier to using Green nor any "vendor lock-in". Always tradeoffs!