Skip to content

Test elapsed times being significantly under-reported when run in parallel (via Django's --parallel option) #229

Open
@bobwhitelock

Description

@bobwhitelock

I have an existing Django project with many tests, and which uses xmlrunner.extra.djangotestrunner.XMLTestRunner from this project as the test runner. I'm using version 3.0.4 of this library on Python 3.7.4.

If I create a file like this in this project:

# notification/tests/test_xmlrunner.py

import time
from django.test import TestCase


class XmlrunnerTest(TestCase):
    def test_wait(self):
        time.sleep(3)

And then run all the tests for this app in serial, I see this result:

$ python manage.py test --keepdb notification
Using existing test database for alias 'default'...
System check identified no issues (0 silenced).

Running tests...
----------------------------------------------------------------------
..............................................................................................................................................
----------------------------------------------------------------------
Ran 142 tests in 59.466s

OK

Generating XML reports...
Preserving test database for alias 'default'...
$ cat TEST-notification.tests.test_xmlrunner.XmlrunnerTest-20201021191521.xml
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: TEST-notification.tests.test_xmlrunner.XmlrunnerTest-20201021191521.xml
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ <?xml version="1.0" encoding="UTF-8"?>
   2   │ <testsuite errors="0" failures="0" file="notification/tests/test_xmlrunner.py" name="notification.tests.test_xmlrunner.XmlrunnerTest-20201021191521" s
       │ kipped="0" tests="1" time="3.001" timestamp="2020-10-21T19:16:19">
   3   │     <testcase classname="notification.tests.test_xmlrunner.XmlrunnerTest" file="notification/tests/test_xmlrunner.py" line="8" name="test_wait" time="
       │ 3.001" timestamp="2020-10-21T19:16:19"/>
   4   │ </testsuite>
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

I.e. the test is recorded as taking just over 3 seconds, as expected.

If I run the tests in parallel via Django's --parallel option, which will run the tests across all 8 cores of my laptop by default, I see this result:

$ python manage.py test --keepdb notification --parallel
Using existing test database for alias 'default'...
Using existing clone for alias 'default'...
Using existing clone for alias 'default'...
Using existing clone for alias 'default'...
Using existing clone for alias 'default'...
Using existing clone for alias 'default'...
Using existing clone for alias 'default'...
Using existing clone for alias 'default'...
Using existing clone for alias 'default'...
System check identified no issues (0 silenced).

Running tests...
----------------------------------------------------------------------
..............................................................................................................................................
----------------------------------------------------------------------
Ran 142 tests in 30.101s

OK

Generating XML reports...
Preserving test database for alias 'default'...
Preserving test database for alias 'default'...
Preserving test database for alias 'default'...
Preserving test database for alias 'default'...
Preserving test database for alias 'default'...
Preserving test database for alias 'default'...
Preserving test database for alias 'default'...
Preserving test database for alias 'default'...
Preserving test database for alias 'default'...
$ cat TEST-notification.tests.test_xmlrunner.XmlrunnerTest-20201021191736.xml
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: TEST-notification.tests.test_xmlrunner.XmlrunnerTest-20201021191736.xml
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ <?xml version="1.0" encoding="UTF-8"?>
   2   │ <testsuite errors="0" failures="0" file="notification/tests/test_xmlrunner.py" name="notification.tests.test_xmlrunner.XmlrunnerTest-20201021191736" s
       │ kipped="0" tests="1" time="0.001" timestamp="2020-10-21T19:17:46">
   3   │     <testcase classname="notification.tests.test_xmlrunner.XmlrunnerTest" file="notification/tests/test_xmlrunner.py" line="8" name="test_wait" time="
       │ 0.001" timestamp="2020-10-21T19:17:46"/>
   4   │ </testsuite>
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

I.e. the test is recorded as having run significantly, and impossibly, faster. I see similar behaviour across almost every test in my test suite when I run them using --parallel.

I need to investigate more, but my current guess is that this is due to some interaction between different tests running in parallel, and the start and end times from different tests often end up being used to calculate the elapsed time for tests.

Would be happy to help with a fix, but would be interested if anyone can reproduce/if you know why this is happening/if you have any suggestions for how best to fix? Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions