views:

202

answers:

2

I'm using the following code in my testing framework:

testModules = ["test_foo", "test_bar"]

suite = unittest.TestLoader().loadTestsFromNames(testModules)
runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
results = runner.run(suite)
return results.wasSuccessful()

Is there a way to make the reporting (runner.run?) abort after the first failure to prevent excessive verbosity?

+3  A: 

It's a feature. If you want to override this, you'll need to subclass TestCase and/or TestSuite classes and override logic in the run() method.

P.S.: I think you have to subclass unittest.TestCase and override method run() in your class:

def run(self, result=None):
    if result is None: result = self.defaultTestResult()
    result.startTest(self)
    testMethod = getattr(self, self._testMethodName)
    try:
        try:
            self.setUp()
        except KeyboardInterrupt:
            raise
        except:
            result.addError(self, self._exc_info())
            return

        ok = False
        try:
            testMethod()
            ok = True
        except self.failureException:
            result.addFailure(self, self._exc_info())
            result.stop()
        except KeyboardInterrupt:
            raise
        except:
            result.addError(self, self._exc_info())
            result.stop()

        try:
            self.tearDown()
        except KeyboardInterrupt:
            raise
        except:
            result.addError(self, self._exc_info())
            ok = False
        if ok: result.addSuccess(self)
    finally:
        result.stopTest(self)

(I've added two result.stop() calls to the default run definition).

Then you'll have to modify all your testcases to make them subclasses of this new class, instead of unittest.TestCase.

WARNING: I didn't test this code. :)

Eugene Morozov
I'm not sure I'm quite capable of that (or rather, I don't wanna put too much effort into this... ).I was hoping there'd be an equivalent of py.test's --exitfirst option.
AnC
Well, there's no other way. Actually, unittest.py code is rather simple - easy to read and extend.
Eugene Morozov
I've looked into this, and tried to override unittest.TextTestRunner.test to abort if a flag was set - but that's the entire set of tests already, so it doesn't help me...Any pointers would be most welcome!
AnC
I've tried to describe one way to solve your problem. It is also possible to create a custom `TestSuite` subclass and override its `run()` method.
Eugene Morozov
Thanks a lot for that - your solution worked, and it allowed me to understand enough to tweak it to be less intrusive - will post a separate reply with details (no markup in comments... ).
AnC
+1  A: 

Based on Eugene's guidance, I've come up with the following:

class TestCase(unittest.TestCase): 
 def run(self, result=None):
  if result.failures or result.errors:
   print "aborted"
  else:
   super(TestCase, self).run(result)

While this works fairly well, it's a bit annoying that each individual test module has to define whether it wants to use this custom class or the default one (a command-line switch, similar to py.test's --exitfirst, would be ideal)...

AnC