Getting tests to parallelize using nose in python

2019-04-25 09:13发布

问题:

I have a directory with lots of .py files (say test_1.py, test_2.py and so on) Each one of them is written properly to be used with nose. So when I run nosetests script, it finds all the tests in all the .py files and executes them.

I now want to parallelize them so that all the tests in all .py files are treated as being parallelizable and delegated to worker processes.

It seems that by default, doing :

nosetests --processes=2 

introduces no parallelism at all and all tests across all .py files still run in just one process

I tried putting a _multiprocess_can_split_ = True in each of the .py files but that makes no difference

Thanks for any inputs!

回答1:

It seems that nose, actually the multiprocess plugin, will make test run in parallel. The caveat is that the way it works, you can end up not executing test on multiple processes. The plugin creates a test queue, spawns multiple processes and then each process consumes the queue concurrently. There is no test dispatch for each process thus if your test are executing very fast, they could end up being executed in the same process.

The following example displays this beaviour:

File test1.py

import os
import unittest

class testProcess2(unittest.TestCase):

    def test_Dummy2(self):
        self.assertEqual(0, os.getpid())

File test2.py

import os
import unittest

class testProcess2(unittest.TestCase):

    def test_Dummy2(self):
        self.assertEqual(0, os.getpid())

Running nosetests --processes=2 outputs (notice the identical process id)

FF
======================================================================
FAIL: test_Dummy2 (test1.testProcess2)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\temp\test1.py", line 7, in test_Dummy2
    self.assertEqual(0, os.getpid())
AssertionError: 0 != 94048

======================================================================
FAIL: test_Dummy1 (test2.testProcess1)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\temp\test2.py", line 8, in test_Dummy1
    self.assertEqual(0, os.getpid())
AssertionError: 0 != 94048

----------------------------------------------------------------------
Ran 2 tests in 0.579s

FAILED (failures=2)

Now if we add a sleep in one of the test

import os
import unittest
import time

class testProcess2(unittest.TestCase):

    def test_Dummy2(self):
        time.sleep(1)
        self.assertEqual(0, os.getpid())

We get (notice the different process id)

FF
======================================================================
FAIL: test_Dummy1 (test2.testProcess1)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\temp\test2.py", line 8, in test_Dummy1
    self.assertEqual(0, os.getpid())
AssertionError: 0 != 80404

======================================================================
FAIL: test_Dummy2 (test1.testProcess2)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\temp\test1.py", line 10, in test_Dummy2
    self.assertEqual(0, os.getpid())
AssertionError: 0 != 92744

----------------------------------------------------------------------
Ran 2 tests in 1.422s

FAILED (failures=2)