views:

709

answers:

3

Hi,

I have a test file that contains tests taking quite a lot of time (they send calculations to a cluster and wait for the result). All of these are in specific TestCase class.

Since they take time and furthermore are not likely to break, I'd want to be able to choose whether this subset of tests does or doesn't run (the best way would be with a command-line argument, ie "./tests.py --offline" or something like that), so I could run most of the tests often and quickly and the whole set once in a while, when I have time.

For now, I just use unittest.main() to start the tests.

Thanks.

+3  A: 

Look into using a dedicated testrunner, like py.test, nose or possibly even zope.testing. They all have command line options for selecting tests.

Look for example as Nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.1/man.html

Lennart Regebro
Thank you for your answer, but I think it's a bit overkill, so I chose the TestSuites one.
Gohu
+1  A: 

You have basically two ways to do it:

  1. Define your own suite of tests for the class
  2. Create mock classes of the cluster connection that will return actual data.

I am a strong proponent of he second approach; a unit test should test only a very unit of code, and not complex systems (like databases or clusters). But I understand that it is not always possible; sometimes, creating mock ups is simply too expensive, or the goal of the test is really in the complex system.

Back to option (1), you can proceed in this way:

suite = unittest.TestSuite()
suite.addTest(MyUnitTestClass('quickRunningTest'))
suite.addTest(MyUnitTestClass('otherTest'))

and then passing the suite to the test runner:

unittest.TextTestRunner().run(suite)

More information on the python documentation: http://docs.python.org/library/unittest.html#testsuite-objects

Roberto Liffredo
Yes, I know about mock objects, but I think this will be too complicated. The python doesn't connect directly to the cluster, it goes through a series of bash scripts whose behavior I need to test. So, I would need to make "mock scripts" that would behave the same as the real ones, except for that last connection part, but then I would have to maintain the two at the same time and make sure that they are equivalent for what I want to test...Thank you for your answer about the test suites, I chose the answer from S. Lott because it is a bit more detailed, but it's basically the same thing.
Gohu
+6  A: 

The default unittest.main() uses the default test loader to make a TestSuite out of the module in which main is running.

You don't have to use this default behavior.

You can, for example, make three unittest.TestSuite instances.

  1. The "fast" subset.

    fast = TestSuite()
    fast.addTests( TestFastThis )
    fast.addTests( TestCastThat )
    
  2. The "slow" subset.

    slow = TestSuite()
    slow.addTests( TestSlowAnother )
    slow.addTests( TestSlowSomeMore )
    
  3. The "whole" set.

    alltests = unittest.TestSuite([fast, slow])
    

Note that I've adjusted the TestCase names to indicate Fast vs. Slow. You can subclass unittest.TestLoader to parse the names of classes and create multiple loaders.

Then your main program can parse command-line arguments with optparse to pick which suite you want to run, fast, slow or all.

Or, you can trust that sys.argv[1] is one of three values and use something as simple as this

if __name__ == "__main__":
    suite = eval(sys.argv[1])
    unittest.TextTestRunner().run(suite)
S.Lott
nice, now if it only it were this easy in c++ land for my algorithm stress tests :)
Matt Joiner