Running tests using OXID testing library

Introduction

This tutorial will show how to run unit/integration and selenium tests on OXID eShop using OXID testing library.

For tutorial I was using these versions of software:

Environment preparation

First of all you need to meet requirements for testing library: https://github.com/OXID-eSales/testing_library/tree/b-1.0#requirements. Also you’ll need module, which will have to be tested. In my case I have module called “example” which is under vendor “mv”.

Now in OXID eShop source directory create composer.json file with content which is described here: https://github.com/OXID-eSales/testing_library/tree/b-1.0#option-1-selecting-shop-directory-for-installation-preferred-way. From now source directory file structure looks like this:

├── source
│   ├── admin
│   ├── application
│   ├── modules
│   │   └── mv
│   │       └── example
│   │           ├── metadata.php
│   │           ├── models
│   │           └── └── MVExampleOxBasket.php
│   ├── bin
│   ├── ...
│   └── composer.json

Locate with console to eShop source directory:

cd <Path to eShop>/source

And run composer installation command:

composer install

Composer will do its job and shortly you’ll have to define 3 parameters:

  1. shop_path – your eShop location. If you are using default structure, you can leave it empty and click enter.
  2. shop_tests_path – eShop tests location. This one also can be left empty, as we are using default structure.
  3. partial_module_paths – module locations. This parameter should be set as we want to test our module. Type vendor name and module name:
    mv/example

    If you would have more modules, you could set paths separated with commas:

    mv/example1,mv/example2

BTW: it’s possible to change these parameters in file which is newly generated and is called test_config.yml and locates in source directory.

 Creating tests

To run tests with OXID testing library you’ll have to define structure of directories as described bellow:

.
├── metadata.php
├── ...
└── tests
    ├── acceptance
    ├── integration
    └── unit

Unit/Integration tests

Let’s say we want customer would see additional text in mini basket, so for this purpose let’s overload oxArticle with our own class and let’s add functionality:

class MVExampleOxBasket extends MVExampleOxBasket_parent
{
    const ITEM_COUNT_NOTE = ' awesome item!';
    const ITEMS_COUNT_NOTE = ' awesome items!';
    public function getItemsCount()
    {
        $itemsCount = parent::getItemsCount();
        return $this->appendTextNearItemsCount($itemsCount);
    }
    public function appendTextNearItemsCount($itemsCount)
    {
        return $itemsCount > 1 ? $itemsCount . static::ITEMS_COUNT_NOTE : $itemsCount . static::ITEM_COUNT_NOTE;
    }
}

I know that it’s probably not the most beautiful code you have ever seen, but don’t forget that it’s only an example 🙂 To test new functionality we have to write unit tests class which must extend oxUnitTestCase:

class MVExampleOxBasketTest extends oxUnitTestCase
{
    public function testAppendsTextForOneItem()
    {
        $mVExampleOxBasketTest = oxNew('MVExampleOxBasket');
        $itemsCount = 1;
        $this->assertSame('1 awesome item!', $mVExampleOxBasketTest->appendTextNearItemsCount($itemsCount));
    }
    public function testAppendsTextForMoreThanOneItem()
    {
        $mVExampleOxBasketTest = oxNew('MVExampleOxBasket');
        $itemsCount = 10;
        $this->assertSame('10 awesome items!', $mVExampleOxBasketTest->appendTextNearItemsCount($itemsCount));
    }
}

Here we have 2 test cases. To run only these test cases and not to run eShop tests, we need to change parameter run_tests_for_shop value in test_config.yml to “false”:

vi test_config.yml
run_tests_for_shop: false

or when executing runtests command tests add environmental parameter in console:

RUN_TESTS_FOR_SHOP=0 vendor/bin/runtests

When I executed command I got this output:

=========
running php version 5.6.9-1~dotdeb+7.1
============
Adding unit tests from /var/www/oxideshop/source/modules/mv/example/tests//unit/*[^8]Test.php
PHPUnit 3.7.38 by Sebastian Bergmann.
Configuration read from /var/www/oxideshop/source/vendor/oxid-esales/testing-library/phpunit.xml
..
Time: 741 ms, Memory: 13.25Mb
OK (2 tests, 2 assertions)

In this way you can run your modules tests + eShop tests, check test_config.yml for possible options.

Acceptance tests

Acceptance tests run using browser and executes any scenario you want. In OXID these tests run using selenium server which can be downloaded here.

First of all we need to activate it, because testing library has no such functionality at this moment. So activation part is up to you. I’ll just go to OXID admin and activate it.

We also don’t want to lose module activation changes in database during test run, so we will have to change test_config.yml file:

install_shop: false

As now everything is prepared we can create test file called MiniBasket.php in acceptance tests directory:

.
├── metadata.php
├── ...
└── tests
├── acceptance
│   └── MiniBasketTest.php
├── integration
└── unit

Newly created test should extend oxAcceptanceTestCase:

class MiniBasketTest extends oxAcceptanceTestCase
{
    public function testChecksMiniBasketCountMessage()
    {
        $this->addToBasket('f4f2d8eee51b0fd5eb60a46dff1166d8', 1, 'start');
        // Need to wait till javascript animations will finish jobs.
        sleep(3);
        $this->assertSame('1 awesome item!', $this->getText('countValue'));
    }
}

Test adds to basket one product and checks if element with id – countValue has expected text.

So now we have activated module and test class. We can run the test with command:

vendor/bin/runtests-selenium

Output:

=========
running php version 5.6.9-1~dotdeb+7.1
============
Adding unit tests from /var/www/oxideshop/source/modules/mv/example/tests//acceptance/*Test\.php
PHPUnit 3.7.38 by Sebastian Bergmann.
Configuration read from /var/www/oxideshop/source/vendor/oxid-esales/testing-library/phpunit.xml
.
Time: 9.99 seconds, Memory: 11.75Mb
OK (1 test, 1 assertion)