PHPUnit bootstrap in PhpStorm

2019-03-31 21:35发布

问题:

I am working with Zend Framework 2 and I want to run tests for all of my modules in PhpStorm 5.0.4. I have PhpStorm set up to check for tests in myproject/module and it successfully finds my tests. The problem is that it doesn't read my configuration file within each module, which is needed (it points to a bootstrap file).

Here is the directory structure for a module (source):

/module
    /User
        /tests
            /UserTest
                /Model
                    /UserTest.php
            Bootstrap.php
            phpunit.xml.dist
            TestConfig.php.dist

When I run the test, it gives me an error because Bootstrap.php is not run prior to running UserTest.php. All of the files are correct, because if I cd to /myproject/module/User/tests/ and run phpunit within the Terminal, it works fine.

I would like it to use the configuration (and thereby bootstrap) within each module. I tried to use the --configuration option with a relative path, but I couldn't get it to work.

Here is my current configuration:

Any pointers on how I can run the configuration file (and bootstrap) when a module is being tested? That is, a module has its own configuration file and bootstrap.

Thanks in advance.

回答1:

PHP Storm 7 assumes that you will only need ONE default bootstrap file and thus does not enable individual bootsrap files DIRECTLY for each PHPUnit test configuration.

However, zf2 conducts tests on a per module basis. Thus, after you set the defaults to the first module the other modules don't work. The way around this is to

  1. Remove the default options in File|Settings|PHP|PHPUnit You don't have to remove the default configuration file but you must EMPTY OUT and uncheck the default bootstrap file. Just unchecking will not be enough

  2. Go Run|Edit Configurations (there are other shortcuts to this box) For each module you have to create a test configuration. For example, you'll have the standard Application Module and thus an "Application Module Test" for it, maybe an Admin Module and then an "Admin Module Test" for that

  3. For each test (assuming standard zf2 directory structure)

a. Test Scope: Directory b. Directory: C:\wamp\www\PROJECT-NAME\module\MODULE-NAME\test c. Check "Use alternative configuration file:" d. Enter C:\wamp\www\PROJECT-NAME\module\MODULE-NAME\test\MODULE-NAMETest\phpunit.xml.dist e. In "Test Runner options", enter "--bootstrap C:\wamp\www\PROJECT-NAME\module\MODULE-NAME\test\MODULE-NAMETest\Bootstrap.php"

  1. Repeat for next module

The issue here is that as long as the default bootsrap field has an entry, phpstorm will add that as default as a --bootstrap option AFTER whatever you put in the case specific Test Runner options. So, no matter what you do, you end up running the wrong bootstrap file everytime except for the first/default test case

Hope this helps



回答2:

Unless I missed something, you'll have to set up a test configuration for each module. In your case, you have myproject. Instead, you'll want one for each module, and then set up the configuration for each (Use alternative configuration file).



回答3:

I make use of the environment variables option in the run configuration to to define a value I can use within a global bootstrap.php to pull in requirements specific to a given module or section of the application.

class GlobalBootstrap
{

private static $applicationSections = [
    'section_a',
    'section_b',
    'section_c'
];

public static function init()
{
    $localMethod = self::fetchLocalMethod();
    if (!is_null($localMethod)) {
        self::$localMethod();
    } else {
       throw new Exception(
            __CLASS__
            . '::'
            . __FUNCTION__
            . 'Says: No local method has been defined for this test section'
        );
    }
}

private static function fetchLocalMethod()
{
    $section = getenv('APPLICATION_SECTION');
    if (is_null($section) || !in_array($section, self::$applicationSections)) {
        return null;
    }
    $section = preg_replace("/[^a-zA-Z]+/", "", $section);
    $method = 'bootstrap' . ucfirst(strtolower($section));

    return $method;
}

/**
 * Section specific methods
 */

protected static function bootstrapSectiona()
{
    require __DIR__ . '/../../{section_a}/module/Test/Bootstrap.php';
}
}

GlobalBootstrap::init();

Any arbitrary variable and value can be created and then referenced in your bootstrap.php using: getevn(VARIABLE_NAME); This saves a lot of long-winded configuration in PHPStorm, but culd potentially get equally as complex if you're relying on a lot of differing bootstrap functionality.