Hi, all,
I'm just finishing up the few changes to enable concurrent unit testing for the LMS unit tests in edx-platform. This will be turned on by default, and will let the tests run across all of the available cores on your machine, which should speed them up noticeably.
Nothing is for free, though, so there are some caveats:
1) Concurrency introduces some amount of indeterminacy in the order of the tests. So, test classes may run in different orders than you've seen them before, and might run in different orders between runs of the tests suite. This is likely not a problem, unless you've accidentally introduced a dependency between your test classes. (Fixing those historical dependencies is actually what I've spent much of this project working on).
2) Because we're already getting some re-ordering of tests, I installed and enabled the 'randomly' plugin for nose, which randomizes the orders of all of the tests. Again, not a problem, unless test classes or test methods have ordering dependencies.
Both of these changes should help root out inter-test dependencies. When tests depend on each other, it hard to distinguish actual failures from failures that happen purely because earlier tests haven't run, which can slow down future development. Ensuring that our tests can run in any order will help keep future development easier.
The new features also add a couple of options to paver: '--no-randomize' will turn off randomization. '--processes=N' will tell the system to only run N processes (useful if you don't want the tests using all of your CPUs). '--extra_args="--randomly-seed=N"' can be useful to reproduce a particular ordering of tests, in case you are seeing what appears to be an order-dependent failure. You can find the seed used during a test run in the test output (when enabled, randomly will add the line 'Using --randomly-seed=XXXXX' to the test output).
If you do see a failure that seems intermittent, please let me know. As I've been working on this, I've seen a couple myself, but they are often hard to reproduce and fix.
As I've been making these changes, here are a number of the failure modes I've had to deal with:
1) Small-value changes to the number of queries being measured by assertNumQueries: this is usually caused by cache dependencies, particularly of things like LanguagePreferences or EmbargoStatus. Usually, these numbers can just be adjusted.
2) Suddenly-missing data: This is often related to a cache now being disabled by default that used to be enabled. The CacheIsolationTestCase (which is a base class of ModulestoreTestCase) allows you to specifically enable caches for certain tests.
3) Unexpected data: Often this is indicative of a resources being shared between concurrently running tests. In my changes, I've isolated the modulestore, the sqlite database used by django, and specific instances of the filesystem (by separating directories). Typically, the solution involves putting a unique identifier in the name of the resource to prevent collisions between test runs.
Thanks
-Cale
p.s. If you want to follow the progress of the pull request, it's
https://github.com/edx/edx-platform/pull/12386