I've got the following tests written for /core/modules/migrate_drupal_ui/src/Controller/MigrateController.php with a new test file /core/modules/migrate_drupal_ui/tests/src/Functional/MigrateControllerTest.php.


namespace Drupal\Tests\migrate_drupal_ui\Functional;

use Drupal\Tests\BrowserTestBase;

 * Provides a base class for testing the Migrate Controller.
abstract class MigrateControllerTest extends BrowserTestBase {
   * {@inheritdoc}
  public static $modules = ['migrate_drupal_ui', 'views'];

   * {@inheritdoc}
  protected function setUp() {
    $account = $this->drupalCreateUser(['administer views']);

  public function testRedirectDestination() {

  public function testRedirectDestinationWithoutView() {
    // Delete the watchdog view

    $this->submitForm([], 'Delete');


Following https://www.drupal.org/docs/8/phpunit/phpunit-browser-test-tutorial, an existing test runs as expected with ../vendor/bin/phpunit --filter testMigrateUpgradeReviewPage modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeFormStepsTest.php.

However, when I do the same for my above test -- ../vendor/bin/phpunit --filter testRedirectDestination modules/migrate_drupal_ui/tests/src/Functional/MigrateControllerTest.php -- I get

PHP Fatal error:  Uncaught PHPUnit\Runner\Exception: Class 'modules/migrate_drupal_ui/tests/src/Functional/MigrateControllerTest' could not be found in '/Users/MrWeiner/Sites/DockerSites/testing/web/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateControllerTest.php'. in /Users/MrWeiner/Sites/DockerSites/testing/web/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php:102

It looks like a namespace issue but I do not understand why it'd be looking for Class 'modules/migrate_drupal_ui/tests/src/Functional/MigrateControllerTest' instead of Class 'Drupal\Tests\migrate_drupal_ui\Functional\MigrateControllerTest'. Do I need to register my test somewhere or do something else to ensure that it's autodiscovered?

Original Question: We've got https://www.drupal.org/files/issues/2019-04-12/adding-custom-access-2904546-24.patch posted in https://www.drupal.org/project/drupal/issues/2904546 with the request "for a functional test with and without that view enabled". The patch itself is very simple so I'd assume that the test would be very simple as well. I just don't have any experience writing tests so I don't really understand what I'd be testing for/asserting here or how to test for both the view existing and not existing.

  • I think this is a bit too broad. heddn mentioned a resource in the issue for getting started with tests. If we take a step back to look at testing in general, usually we want to assert one value (or behavior) that is expected from an issue, user story, acceptance criteria, or whatever. So if "admin/reports/upgrade doesn't correctly redirect. If views is enabled, it should use URL arguments instead of setting the session" is the issue summary, then we should assert we are at a given URL after clicking a link or whatever.
    – mradcliffe
    Commented Apr 16, 2019 at 1:40
  • 1
    Thanks @mradcliffe, I think your comment helped me to break down what was required. I've edited the question to refer to a specific error I'm receiving now instead of the broader question regarding testing.
    – Mrweiner
    Commented Apr 16, 2019 at 20:09

1 Answer 1


It turns out that the issue was that MigrateControllerTest was defined as an abstract class. Defining it as a regular class cleared this up.

  • Ah, yes. Abstract classes can only be extended, not instantiated.
    – Kevin
    Commented Apr 17, 2019 at 19:53
  • Who would have thought that copying code straight from another test wouldn't work as expected?!
    – Mrweiner
    Commented Apr 17, 2019 at 19:58
  • It's another test? Or is it a class that a test extends from (to provide common setups)?
    – Kevin
    Commented Apr 17, 2019 at 20:00
  • I think it was MigrateUpgradeExecuteTestBase and I'd assumed it was running actual tests since it contains the method testMigrateUpgradeExecute. I saw/see that it has "base" in the name, so I figured it was being leveraged elsewhere but I didn't understand that it could inherently only be extended
    – Mrweiner
    Commented Apr 17, 2019 at 20:12
  • I don't have anything in front of me so take this with a grain of salt, but since the class name does not end in Test that it was skipped. I.E. MigrateUpgradeExecuteTestBase is never ran, you'd extend that and that class would end with Test and executed. Like class My MigrateUpgradeExecuteTest extends MigrateUpgradeExecuteTestBase. In your code posted above, you'd just change your class to MigrateControllerTestBase, then extend that with the actual test class. More on abstract classes: php.net/manual/en/language.oop5.abstract.php
    – Kevin
    Commented Apr 17, 2019 at 20:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.