On 15/02/2010 17:05, Michael Foord wrote:
[snip]
This is also an interesting point. The 'naive' implementation, which I think I prefer, only runs the setUpModule of modules actually containing tests. Similarly setUpClass is only called on classes with actual tests, although they may call up to base class implementations.

This has a couple of consequences, particularly for setUpModule. It makes the basic rule:

* only use setUpModule for modules actually containing tests
* don't mix concrete TestCases (with tests) in the same module (using setUpModule) as base classes for other tests

The use case (that I can think of) that isn't supported (and of course all this needs to be documented):

* Having setUpModule / tearDownModule in modules that define base classes and expecting them to be called around all tests that inherit from those base classes

Having this in place makes the implementation simpler. If we explicitly document that this rule may change and so users shouldn't rely on setUpModule not being called for modules containing base classes, then we are free to rethink it later. Not having this restriction at all is possible, it just requires more introspection at TestSuite creation / ordering time.

Note that setUpClass on a base class maybe called several times if several base classes inherit and all call up to the base class implementation. As it will be a class method the cls argument will be different for each call.

Another question. If we are implementing TestCase.setUpClass as an additional test then should it be reported *even* if it is only the default (empty) implementation that is used?

The reason to have setUpClass implemented as a test is so that you can report the failure *before* you run all the tests. Lots of unit test users want a consistent number of tests every run - so we shouldn't insert an extra test only on fail. The other alternative is to report a setUpClass failure as part of the first test that depends on it - this makes the implementation more, complex (having a pseudo-test represent setUpClass / tearDownClass is convenient for ordering and isolating the 'magic' in one place - the rest of the test running infrastructure doesn't need to know about setUpClass or Module).

If we do add a default setUpClass test for all TestCases it means extra noise for test runs that don't use the new feature. Saying no it shouldn't be shown means that we have to introspect test classes to see if they inherit setUpClass from TestCase or from some intermediate base class. Not hard just an extra complexity. One solution would be for TestCase *not* to have default implementations, but it is probably nicer for them to appear in the API.

I guess my preferred approach is to have a default implementation, but not to create pseudo-tests for them if they aren't used.


One place to implement this is in the TestLoader (specifically in loadTestsFromModule and loadTestsFromTestCase) - especially as this is the place where test ordering is currently provided by unittest. The TestSuite may not need to change much. This isn't compatible with test frameworks that build custom suites without going through loadTestsFromModule - e.g. modules implementing load_tests that replace the standard test suite with a new suite with specific TestCases and still expect setUpModule / tearDownModule to be used [1]. Perhaps an API hook to make this easy?

TestCase would need a change in run(...) to support automatic SetupFailed test failing when setUpClass / module fails.

This *isn't* compatible with custom TestSuites that reorder tests. The alternative is for TestSuite.run(...) to change to support setUpClass / setUpModule by adding them at test run time by introspecting contained tests. That would make setUpClass (etc) incompatible with custom TestSuite implementations that override run. It would be compatible with TestSuites that do reordering but that don't overload run(...) - although the resulting test order may not be 'optimal' (the setUp and tearDown may end up separated farther in time than desired but at least they would work). Perhaps this approach is less likely to break? (Manually reordering tests or adding new tests to a TestSuite wouldn't break setUpClass as the TestSuite only adds them at run(...) time rather than placing them in the suite where the 'user' can move them around).

All the best,

Michael

[1] or even load_tests that just addTests to the standard suite but still need tearDownModule to be run *after* all the tests. Even with the implementation in loadTestsFrom* it seems like the TestSuite may need to know something about the order. Perhaps we could have TestLoader.orderTests - the loader is available to load_tests functions.



All the best,

Michael

testresources very neatly sidesteps this problem by just providing an API to say "this test case depends on that test resource", without relying on the grouping of tests within classes, modules, or packages. Of course you can just define a class-level or module-level resource and then have all your tests depend on it, which gives you the behavior of setUpClass and setUpModule in a more general way.

-glyph





--
http://www.ironpythoninaction.com/
http://www.voidspace.org.uk/blog

READ CAREFULLY. By accepting and reading this email you agree, on behalf of 
your employer, to release me from all obligations and waivers arising from any 
and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, 
clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and 
acceptable use policies (”BOGUS AGREEMENTS”) that I have entered into with your 
employer, its partners, licensors, agents and assigns, in perpetuity, without 
prejudice to my ongoing rights and privileges. You further represent that you 
have the authority to release me from any BOGUS AGREEMENTS on behalf of your 
employer.


_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to