diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index 4a600dc..8cf5623 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -756,31 +756,83 @@ function simpletest_phpunit_xml_to_rows($test_id, $phpunit_xml_file) {
   $records = array();
   foreach ($xml->testsuite as $testsuite) {
     foreach ($testsuite as $suite) {
-      foreach ($suite as $testcase) {
-        $message = '';
-        $pass = TRUE;
-        if ($testcase->failure) {
-          $lines = explode("\n", $testcase->failure);
-          $message = $lines[2];
-          $pass = FALSE;
-        }
-        if ($testcase->error) {
-          $message = $testcase->error;
-          $pass = FALSE;
-        }
-        $attributes = $testcase->attributes();
-        $records[] = array(
-          'test_id' => $test_id,
-          'test_class' => (string) $attributes->class,
-          'status' => $pass ? 'pass' : 'fail',
-          'message' => $message,
-          'message_group' => 'Other', // TODO: Check on the proper values for this.
-          'function' => $attributes->class . '->' . $attributes->name . '()',
-          'line' => (int) $attributes->line,
-          'file' => (string) $attributes->file,
-        );
+      // The file element won't be on testcase objects created with
+      // @dataProvider, so just use the one from the test suite at this level
+      // because it should be the same.
+      $file = (string)$suite->attributes()->file;
+
+      $testcases = simpletest_phpunit_find_testcases($suite);
+      foreach ($testcases as $testcase) {
+        $records[] = simpletest_phpunit_testcase_to_row($test_id, $testcase, $file);
       }
     }
   }
   return $records;
 }
+
+/**
+ * Find all testcases recursively from a testsuite list.
+ *
+ * @param array $suite
+ *   The list of testcases contained in the PHPUnit XML.
+ *
+ * @return array
+ *   A list of all testcases.
+ */
+function simpletest_phpunit_find_testcases($suite) {
+  $testcases = array();
+
+  foreach ($suite as $testcase) {
+    // Beside from being 'testcases', it could be also a group of testcases.
+    // This happens if you use a data provider in the phpunit tests.
+    if ($testcase->getName() === 'testcase') {
+      $testcases[] = $testcase;
+    }
+    elseif (isset($testcase->testcase) && $testcase->tests > 0) {
+      foreach ($testcase->testcase as $childtestcase) {
+        $testcases[] = $childtestcase;
+      }
+    }
+  }
+  return $testcases;
+}
+
+/**
+ * Converts a PHPUnit testcase result to a simpletest result row.
+ *
+ * @param int $test_id
+ *   The current test ID.
+ * @param \SimpleXMLElement $testcase
+ *   The PHPUnit testcase represented as xml element.
+ * @param string $file
+ *   The path to test file, which was executed.
+ * @return array
+ *   An array containg the simpletest result row.
+ */
+function simpletest_phpunit_testcase_to_row($test_id, \SimpleXMLElement $testcase, $file) {
+  $message = '';
+  $pass = TRUE;
+  if ($testcase->failure) {
+    $lines = explode("\n", $testcase->failure);
+    $message = $lines[2];
+    $pass = FALSE;
+  }
+  if ($testcase->error) {
+    $message = $testcase->error;
+    $pass = FALSE;
+  }
+
+  $attributes = $testcase->attributes();
+
+  $record = array(
+    'test_id' => $test_id,
+    'test_class' => (string)$attributes->class,
+    'status' => $pass ? 'pass' : 'fail',
+    'message' => $message,
+    'message_group' => 'Other', // TODO: Check on the proper values for this.
+    'function' => $attributes->class . '->' . $attributes->name . '()',
+    'line' => $attributes->line ?: 0,
+    'file' => $file,
+  );
+  return $record;
+}
diff --git a/core/modules/simpletest/tests/Drupal/simpletest/Tests/PhpUnitErrorTest.php b/core/modules/simpletest/tests/Drupal/simpletest/Tests/PhpUnitErrorTest.php
index b6c19d9..224e921 100644
--- a/core/modules/simpletest/tests/Drupal/simpletest/Tests/PhpUnitErrorTest.php
+++ b/core/modules/simpletest/tests/Drupal/simpletest/Tests/PhpUnitErrorTest.php
@@ -24,8 +24,16 @@ public function testPhpUnitXmlParsing() {
     require_once __DIR__ . '/../../../../simpletest.module';
     $phpunit_error_xml = __DIR__ . '/phpunit_error.xml';
     $res = simpletest_phpunit_xml_to_rows(1, $phpunit_error_xml);
+    $this->assertEquals(count($res), 4, 'All testcases got extracted');
     $this->assertNotEquals($res[0]['status'], 'pass');
     $this->assertEquals($res[0]['status'], 'fail');
+
+    // Test nested testsuites, which appear when you use @dataProvider.
+    for ($i = 0; $i < 3; $i++) {
+      $this->assertNotEquals($res[$i + 1]['status'], 'pass');
+      $this->assertEquals($res[$i + 1]['status'], 'fail');
+    }
+
     // Make sure simpletest_phpunit_xml_to_rows() does not balk if the test
     // didn't run.
     simpletest_phpunit_xml_to_rows(1, 'foobar');
diff --git a/core/modules/simpletest/tests/Drupal/simpletest/Tests/phpunit_error.xml b/core/modules/simpletest/tests/Drupal/simpletest/Tests/phpunit_error.xml
index b1c0837..9ce6f6b 100644
--- a/core/modules/simpletest/tests/Drupal/simpletest/Tests/phpunit_error.xml
+++ b/core/modules/simpletest/tests/Drupal/simpletest/Tests/phpunit_error.xml
@@ -18,4 +18,26 @@ Undefined index: foo
     <testsuite name="Drupal\Tests\Core\NestedArrayUnitTest" file="/home/chx/www/system/core/tests/Drupal/Tests/Core/NestedArrayUnitTest.php" namespace="Drupal\Tests\Core" fullPackage="Drupal.Tests.Core" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
     <testsuite name="Drupal\breakpoint\Tests\BreakpointMediaQueryTest" file="/home/chx/www/system/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php" namespace="Drupal\breakpoint\Tests" fullPackage="Drupal.breakpoint.Tests" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
   </testsuite>
+  <testsuite name="Drupal\Tests\Core\Route\RouterRoleTest" file="/var/www/d8/core/tests/Drupal/Tests/Core/Route/RouterRoleTest.php" namespace="Drupal\Tests\Core\Route" fullPackage="Drupal.Tests.Core.Route" tests="3" assertions="3" failures="3" errors="0" time="0.009176">
+    <testsuite name="Drupal\Tests\Core\Route\RouterRoleTest::testRoleAccess" tests="3" assertions="3" failures="3" errors="0" time="0.009176">
+      <testcase name="testRoleAccess with data set #0" assertions="1" time="0.004519">
+        <failure type="PHPUnit_Framework_ExpectationFailedException">Drupal\Tests\Core\Route\RouterRoleTest::testRoleAccess with data set #0 ('role_test_1', array(Drupal\user\Plugin\Core\Entity\User, Drupal\user\Plugin\Core\Entity\User))
+          Access granted for user with the roles role_test_1 on path: role_test_1
+          Failed asserting that false is true.
+        </failure>
+      </testcase>
+      <testcase name="testRoleAccess with data set #1" assertions="1" time="0.002354">
+        <failure type="PHPUnit_Framework_ExpectationFailedException">Drupal\Tests\Core\Route\RouterRoleTest::testRoleAccess with data set #1 ('role_test_2', array(Drupal\user\Plugin\Core\Entity\User, Drupal\user\Plugin\Core\Entity\User))
+          Access granted for user with the roles role_test_2 on path: role_test_2
+          Failed asserting that false is true.
+        </failure>
+      </testcase>
+      <testcase name="testRoleAccess with data set #2" assertions="1" time="0.002303">
+        <failure type="PHPUnit_Framework_ExpectationFailedException">Drupal\Tests\Core\Route\RouterRoleTest::testRoleAccess with data set #2 ('role_test_3', array(Drupal\user\Plugin\Core\Entity\User))
+          Access granted for user with the roles role_test_1, role_test_2 on path: role_test_3
+          Failed asserting that false is true.
+        </failure>
+      </testcase>
+    </testsuite>
+  </testsuite>
 </testsuites>
