EcomDev_PHPUnit Tip #7

For years, the test framework EcomDev_PHPUnit is quasi-standard for Magento unit tests. The current version is 0.3.7 and last state of official documentation is version 0.2.0 – since then, much has changed which you have to search yourself in code and GitHub issues. This series shall collect practical usage tips.

Tip #7: YAML Directory Fallback

YAML files for fixtures, expectations and data providers are expected in the following scheme by default, where in this example Importer.php contains the test case and testImport is the test method:

│   Importer.php
│
├───Importer
│   ├───expectations
│   │       testImport.yaml
│   │
│   ├───fixtures
│   │       testImport.yaml
│   │
│   └───providers
│           testImport.yaml

Here the signature with annotations:

    /**
     * @param string $csv CSV file content
     * @test
     * @loadFixture
     * @loadExpectation
     * @dataProvider dataProvider
     */
    public function testImport($csv)

Instead of the method name the file name of the YAML file can also be stated explicitly, like in this example where another test also uses fixtures/testImport.yaml (how this also works for data providers, see Tip #3).

    /**
     * @param string $csv CSV file content
     * @test
     * @loadFixture testImport
     * @dataProvider dataProvider
     * @expectedException RuntimeException
     */
    public function testFailingImport($csv)

But even the directory structure doesn’t have to be used in this form. If EcomDev_PHPUnit doesn’t find the according file in this place, the following fallback hierarchy is used:

  1. Default: see above
  2. Module: The directories “fixtures”, “expectations” and “providers” are searched directly in the “Test” directory of the module
  3. Global: The directories are searched in any parent directory of the test case up until the Magento root

This way you can use fixtures etc. across multiple test cases. Today I prefer the second variant for module wide definition in most cases, at least for fixtures.

Incidentally, the hierarchy is defined in the EcomDev_PHPUnit config.xml as follows:

<config>
    <phpunit>
        <suite>
            <yaml>
                <model>ecomdev_phpunit/yaml_loader</model>
                <loaders>
                    <default>ecomdev_phpunit/yaml_loader_default</default>
                    <module>ecomdev_phpunit/yaml_loader_module</module>
                    <global>ecomdev_phpunit/yaml_loader_global</global>
                </loaders>
            </yaml>
        </suite>
    </phpunit>
</config>

These loaders are models which inherit from EcomDev_PHPUnit_Model_Yaml_AbstractLoader, so with an own module you theoretically can add own custom loaders to use arbitrary sources for the YAML files.

3 Replies to “EcomDev_PHPUnit Tip #7”

  1. Sehr guter Hinweis!

    Ich habe einfach den FixtureLoader überschrieben, aber diese Lösung ist wesentlich besser, da sie sich in verschiedenen Umgebungen einsetzen lässt.

    In meinem Fall habe ich einen Fixture-Ordner in einem von “EcomDev” abweichenden Konvention, weshalb das Fallback-Modell nicht mehr greift.

    Hast du hierzu auch eine Lösungsoption?

    Grüße

    1. Was genau ist das Problem? Mit einem eigenen Loader, der von der Konvention abweicht funktioniert das Fallback-Modell immer noch.

      Wenn du das verhindern willst, kannst du wahrscheinlich auch die <default>, <module> und <global> Nodes in deiner Konfiguration überschreiben, und somit die Standard-Loader deaktivieren.

  2. Genau das habe ich gemacht. Habe einfach den Loader überschrieben. Das Problem war bei mir, dass die fixtures usw. in einem ganz anderen Ordner liegen.

    ecomdev_phpunit/yaml_loader_default
    ecomdev_phpunit/yaml_loader_module
    mothership_phpunit/yaml_loader_recursive

Comments are closed.