[TIP] stop suite after failure
loigu
loigu at volny.cz
Fri Jan 4 03:08:34 PST 2008
Kumar McMillan wrote:
> On Jan 3, 2008 5:54 AM, loigu <loigu at volny.cz> wrote:
>
>> Thanks for your response,
>>
>> The approach with startTest doesn't work -- returning True just prevents
>> other plugins from seeing the test start, doesn't prevent test itself
>> from starting.
>>
>
> Hmm, I think there must be a way to have a plugin stop the test. Did
> you try the want* methods? Like:
>
> class FailureThreshold(Plugin):
> # ...as defined above
> def _wantTestObject(self, test):
> level = getattr(test, 'threshold', None)
> if level is not None and level >= self.failure_threshold:
> return False
> wantClass = _wantTestObject
> wantFunction = _wantTestObject
> wantMethod = _wantTestObject
>
Yes you can do this but BEFORE any test run. So if you want to run test
depending on others results using want_ methods it forces you to run one
test after another manually.
I know that it's rather rare to want this feature in unit testing (unit
tests should be small and fast - so why bother) but when small unit test
runs above distributed filesystem... :/
> ...if that doesn't work I'd suggest posting on the nose list and after
> that submitting a feature request ;) I think a plugin should be able
> to stop a test based on a test's attributes.
>
> Kumar
>
>
>> Currently I use this approach:
>> I had subclassed nose.suite.ContextSuite and replaced the run method
>> with something like
>>
>> ....
>> ....
>> #main loop
>> try:
>> for test in self._tests:
>> if result.shouldStop:
>> log.debug("stopping")
>> break
>> # each nose.case.Test will create its own result
>> proxy
>> # so the cases need the original result, to
>> avoid proxy
>> # chains
>> test(orig)
>> #here is the only difference against original function
>>
>> if getattr(test,'stopContext', None):
>> break;
>> finally:
>> self.has_run = True
>> ....
>> ....
>>
>> Then in plugin I'm generating the context suite with tests ordered and
>> in handleFailure and handleError I'm setting the stopContext attribute.
>>
>>
>> This approach works but it's not as maintainable as i would like to.
>>
>> All the best,
>>
>> Jiri Zouhar
>>
>>
>>
>> Kumar McMillan wrote:
>>
>>> On Dec 29, 2007 4:45 PM, loigu <loigu at volny.cz> wrote:
>>>
>>>
>>>> Hi,
>>>>
>>>> Does anybody know if it is possible to stop context suite execution
>>>> after test failure without preventing other suites to run?
>>>>
>>>> What I'm trying to do:
>>>>
>>>> I have test class containing some tests (trivial, but with non-trivial
>>>> time consumption).
>>>> There can be defined ordering on them (if test N fails, all tests > N
>>>> fails too).
>>>> So in this case it would be nice to stop after failure and do not run
>>>> other tests from the same class (we know that they will fail),
>>>> but continue in execution of other test suites.
>>>>
>>>> Is it there some easy or preferred way to do this?
>>>> Or it is nonsense to do such a thing?
>>>>
>>>>
>>> One way you could do this is to use nose
>>> (http://somethingaboutorange.com/mrl/projects/nose/). You would
>>> assign attributes to your tests to define the level and create a
>>> custom plugin to skip tests when the threshold has been reached.
>>>
>>> Here is some more info on writing nose plugins:
>>> http://somethingaboutorange.com/mrl/projects/nose/doc/writing_plugins.html
>>> http://somethingaboutorange.com/mrl/projects/nose/doc/plugin_interface.html
>>>
>>> You'd assign attributes like so:
>>>
>>> def test_beans():
>>> assert 1==2
>>> test_beans.threshold = 5
>>>
>>> def test_rice():
>>> # relates somehow to beans
>>> assert 1==3
>>> test_rice.threshold = 6
>>>
>>> Then a plugin would look something like this:
>>>
>>> from nose.plugins import Plugin
>>> class FailureThreshold(Plugin):
>>> name = "failure-threshold"
>>> def configure(self, options, conf):
>>> Plugin.configure(self, options, conf)
>>> if not self.enabled:
>>> return
>>> self.failure_threshold = 0
>>>
>>> def addError(self, test, err):
>>> level = getattr(test, 'threshold', None)
>>> if level is not None and level < self.failure_threshold:
>>> # honor the lowest failing level
>>> self.failure_threshold = level
>>> addFailure = addError
>>>
>>> def startTest(self, test):
>>> level = getattr(test, 'threshold', None)
>>> if level is not None and level >= self.failure_threshold:
>>> return True # prevents the test from running, *I think*
>>>
>>>
>>>
>>> ...untested, of course. However, if you are creating tests that
>>> depend on another test in some way I would suggest trying to decouple
>>> that dependency. You can probably do so by inheriting common
>>> setUp/tearDown methods. Otherwise, if you are just trying to make a
>>> logical guess as to what might start failing next then your approach
>>> sounds like it might save some cpu time. You may also find that
>>> manually declaring "levels" will become fragile and error prone so if
>>> you can find a way to introspect the level instead, that would
>>> probably be better.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>> Thanks,
>>>>
>>>> Jiri Zouhar
>>>>
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> testing-in-python mailing list
>>>> testing-in-python at lists.idyll.org
>>>> http://lists.idyll.org/listinfo/testing-in-python
>>>>
>>>>
>>>>
>>> _______________________________________________
>>> testing-in-python mailing list
>>> testing-in-python at lists.idyll.org
>>> http://lists.idyll.org/listinfo/testing-in-python
>>>
>>>
>>>
>>>
>> _______________________________________________
>> testing-in-python mailing list
>> testing-in-python at lists.idyll.org
>> http://lists.idyll.org/listinfo/testing-in-python
>>
>>
>
>
>
More information about the testing-in-python
mailing list