Repository: django/django
File: tests/test_runner/test_parallel.py (Python)

Code before:
        self.assertIsInstance(actual_test, TestCase)
        self.assertEqual(actual_test.id(), "unittest.case.TestCase.runTest")
        self.assertIn("Traceback (most recent call last):", tb_and_details_str)
        self.assertIn("ValueError: woops", tb_and_details_str)

    def test_handle_add_success(self):
        dummy_subsuites = []
        pts = ParallelTestSuite(dummy_subsuites, processes=2)
        result = TestResult()
        test = TestCase()
        event = ("addSuccess", 0)
        pts.handle_event(result, tests=[test], event=event)

        self.assertEqual(len(result.errors), 0)
        self.assertEqual(len(result.failures), 0)


class ParallelBufferTest(DjangoTestCase):
    def test_parallel_buffer(self):
        """
        Test that ParallelTestSuite.run() properly handles buffered TestResult
        to prevent AttributeError when setUpTestData raises exceptions.
        Before the fix, running tests with
        --parallel --buffer would crash with AttributeError when setUpTestData
        raised an exception because the main process TestResult had buffer=True
        but _setupStdout() was never called.
        """

        class AbortingTest(DjangoTestCase):
            @classmethod
            def setUpTestData(cls):
                raise RuntimeError("Boo!")

            def test_pass(self):
                pass

        test = AbortingTest("test_pass")
        remote_result = RemoteTestResult()
        suite = TestSuite([test])
        suite.run(remote_result)

        pts = ParallelTestSuite([suite], processes=2, buffer=True)
        pts.serialized_aliases = set()
        test_result = TestResult()
        test_result.buffer = True

        with unittest.mock.patch("multiprocessing.Pool") as mock_pool:

            def fake_next(*args, **kwargs):
                test_result.shouldStop = True
                return (0, remote_result.events)

Review comment (suggestion):
Per [contributing guidelines](https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/#:~:text=In%20test%20docstrings%2C%20state%20the%20expected%20behavior%20that%20each%20test%20demonstrates%2E%20Don%E2%80%99t%20include%20preambles%20such%20as%20%E2%80%9CTests%20that%E2%80%9D%20or%20%E2%80%9CEnsures%20that%E2%80%9D%2E):

> In test docstrings, state the expected behavior that each test demonstrates. Don’t include preambles such as “Tests that” or “Ensures that”.

Also no need to fully explain the issue - again we have `git blame` and the ticket for that.

```suggestion
        ParallelTestSuite.run() with `buffer=True` correctly handles test
        cases with setUpClass().
```


Code after:
        self.assertEqual(actual_test.id(), "unittest.case.TestCase.runTest")
        self.assertIn("Traceback (most recent call last):", tb_and_details_str)
        self.assertIn("ValueError: woops", tb_and_details_str)

    def test_handle_add_success(self):
        dummy_subsuites = []
        pts = ParallelTestSuite(dummy_subsuites, processes=2)
        result = TestResult()
        test = TestCase()
        event = ("addSuccess", 0)
        pts.handle_event(result, tests=[test], event=event)

        self.assertEqual(len(result.errors), 0)
        self.assertEqual(len(result.failures), 0)

    def test_buffer_mode_reports_setupclass_failure(self):
        test = SampleErrorTest("dummy_test")
        remote_result = RemoteTestResult()
        suite = TestSuite([test])
        suite.run(remote_result)

        pts = ParallelTestSuite([suite], processes=2, buffer=True)
        pts.serialized_aliases = set()
        test_result = TestResult()
        test_result.buffer = True

        with unittest.mock.patch("multiprocessing.Pool") as mock_pool:

            def fake_next(*args, **kwargs):
                test_result.shouldStop = True
                return (0, remote_result.events)

            mock_pool.return_value.imap_unordered.return_value = unittest.mock.Mock(
                next=fake_next
            )
            pts.run(test_result)

        self.assertIn("ValueError: woops", test_result.errors[0][1])