PHP Unit

TestDox Notation

Test Dox is a way of naming tests that can be used to provide Agile Documentation for the classes that you create

In order to make use of this you need to make some small changes to the way your tests are setup.

Class Annotations

In the class level docblock, you need to indicate which class the test is covering. This is done like so

1
2
3
4
5
6
7
8
9
<?php declare(strict_types = 1);

namespace EdmondsCommerce\Example\Tests\Model\ExampleTest;

/**
 * Class ExampleTest
 * @testdox EdmondsCommerce\Example\Model\Example
 */
class ExampleTest

You can use the same same @testdox across multiple test classes and the results will be grouped together

Method Naming / Annotation

There are two ways of doing this. The way I prefer is as follows

1
2
3
4
5
6
7
8
9
<?php

    /**
     * @test
     */
    public function canCreateTheClassUsingTheFactory()
    {
        /* Your test goes here */
    }

This will be converted into Can Create The Class Using The Factory. There are other ways of doing this, you can use the @testdox annotation on the method, or you can prefix the method with test which will then be stripped out of the description

Updating the phpunit.xml file

To get the full benefit of using this, you will want to see the notation as the tests run. To do this, you need to change the default printer that phpunit uses.

This is done by adding a printerClass to the XML file like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<phpunit
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
        backupGlobals="false"
        bootstrap="tests/bootstrap.php"
        cacheTokens="false"
        colors="true"
        convertErrorsToExceptions="true"
        convertNoticesToExceptions="true"
        convertWarningsToExceptions="true"
        syntaxCheck="true"
        verbose="true"
        printerClass="\PHPUnit\Util\TestDox\CliTestDoxPrinter">
    <!-- ... -->
</phpunit>

Configure XDebug

Running your tests with XDebug is required to generate code coverage, however it will slow down the running of them significantly.

Since version 2.6, XDebug has been able to whitelist the files it will generate coverage for, which significantly speeds this up, see here for more details.

One problem with this is that it can not handle relative paths correctly, i.e. /path/to/config/../src.

Assuming that you are using the qaConfig directory to hold you config, add the following file to it

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php declare(strict_types=1);
if (!\function_exists('xdebug_set_filter')) {
    return;
}

$srcDirectory = dirname(__DIR__) . '/src';

\xdebug_set_filter(
    \XDEBUG_FILTER_CODE_COVERAGE,
    \XDEBUG_PATH_WHITELIST,
    [
        $srcDirectory
    ]
);

You then need to require this in your bootstrap.php file, and the tests should run almost twice as fast

Php Unit Testing for New Developers

Getting Started

  • Installation
  • If you need settings or dependencies or just required extra predefined variables then you can include custom configuration file in Phpunit test
  • In phpunit.xml file add teh file in bootstrap <phpunit bootstrap="testsSettings.php">
  • It will be include in the tests and you can access the data like global $data (variable name)

Help Notes

  • You should think about testing the module from start
  • Use 'expect' and 'actual' with the variables names e.g. this->assertEquals($expectedValue, $actualValue).
  • This is so later we know how the assertion is taking values

Magento Problems with Different Data

  • Some times we can not use the live database for testing as if we change the value then it can be a problem.
  • so the values saved in admin won't be available for testing
  • For this we create a file config.yaml which contains the paths and the values which are needed
  • e.g
    1
    2
    3
    4
    5
    config:
        default/feed/access/host: https://outlets.goldline.co.uk/Outlets/GetXMLPrices.asp?OutletNo={USER}&Initials={TOKEN}&Password={PASS}
        default/feed/access/user: 17075
        default/feed/access/pass: Precious
        default/feed/access/token: TOP
    
  • include the file then before it's needed
  • e.g - (fixtures is folder name)
    1
    2
    3
    4
    5
    6
    7
        /**
         * @loadFixture ../fixtures/config.yaml
         */
        public function testSomeFunction()
        {
            //test here
        }
    
  • now you can get the value like Mage::getStoreConfig('VALUE/PATH');