Python unittest.TestCase execution order

Is there a way in Python unittest to set the order in which test cases are run?

In my current TestCase class, some testcases have side effects that set conditions for the others to run properly. Now I realize the proper way to do this is to use setUp() to do all setup related things, but I would like to implement a design where each successive test builds slightly more state that the next can use. I find this much more elegant.

class MyTest(TestCase):

  def test_setup(self):
    # Do something

  def test_thing(self):
    # Do something that depends on test_setup()

Ideally, I would like the tests to be run in the order they appear in the class. It appears that they run in alphabetical order.


Don't make them independent tests - if you want a monolithic test, write a monolithic test.

class Monolithic(TestCase):
  def step1(self):
      ...

  def step2(self):
      ...

  def _steps(self):
    for name in dir(self): # dir() result is implicitly sorted
      if name.startswith("step"):
        yield name, getattr(self, name) 

  def test_steps(self):
    for name, step in self._steps():
      try:
        step()
      except Exception as e:
        self.fail("{} failed ({}: {})".format(step, type(e), e))

If the test later starts failing and you want information on all failing steps instead of halting the test case at the first failed step, you can use the subtests feature: https://docs.python.org/3/library/unittest.html#distinguishing-test-iterations-using-subtests

(The subtest feature is available via unittest2 for versions prior to Python 3.4: https://pypi.python.org/pypi/unittest2 )


It's a good practice to always write a monolithic test for such expectations. However, if you are a goofy dude like me, then you could simply write ugly looking methods in alphabetical order so that they are sorted from a to b as mentioned in the Python documentation - unittest — Unit testing framework

Note that the order in which the various test cases will be run is determined by sorting the test function names with respect to the built-in ordering for strings

Example

  def test_a_first():
  print "1"
  def test_b_next():
  print "2"
  def test_c_last():
  print "3"

From unittest — Unit testing framework, section Organizing test code:

Note: The order in which the various tests will be run is determined by sorting the test method names with respect to the built-in ordering for strings.

So just make sure test_setup's name has the smallest string value.

Note that you should not rely on this behavior — different test functions are supposed to be independent of the order of execution. See ngcohlan's answer above for a solution if you explicitly need an order.


Another way that I didn't see listed in any related questions: Use a TestSuite.

Another way to accomplish ordering is to add the tests to a unitest.TestSuite. This seems to respect the order in which the tests are added to the suite using suite.addTest(...). To do this:

  • Create one or more TestCase subclasses,

      class FooTestCase(unittest.TestCase):
          def test_ten():
              print('Testing ten (10)...')
          def test_eleven():
              print('Testing eleven (11)...')
    
      class BarTestCase(unittest.TestCase):
          def test_twelve():
              print('Testing twelve (12)...')
          def test_nine():
              print('Testing nine (09)...')
    
  • Create a callable test-suite generation added in your desired order, adapted from the documentation and this question:

      def suite():
          suite = unittest.TestSuite()
          suite.addTest(BarTestCase('test_nine'))
          suite.addTest(FooTestCase('test_ten'))
          suite.addTest(FooTestCase('test_eleven'))
          suite.addTest(BarTestCase('test_twelve'))
          return suite
    
  • Execute the test-suite, e.g.,

      if __name__ == '__main__':
          runner = unittest.TextTestRunner(failfast=True)
          runner.run(suite())
    

For context, I had a need for this and wasn't satisfied with the other options. I settled on the above way of doing test ordering.

I didn't see this TestSuite method listed any of the several "unit-test ordering questions" (e.g., this question and others including execution order, or changing order, or tests order).


I ended up with a simple solution that worked for me:

class SequentialTestLoader(unittest.TestLoader):
    def getTestCaseNames(self, testCaseClass):
        test_names = super().getTestCaseNames(testCaseClass)
        testcase_methods = list(testCaseClass.__dict__.keys())
        test_names.sort(key=testcase_methods.index)
        return test_names

And then

unittest.main(testLoader=utils.SequentialTestLoader())