Skip to content

Testing your module

Hervé Schoenenberger edited this page Jul 6, 2023 · 3 revisions

Setting up PHPUnit for PrestaShop modules

This documentation aims at setting up a PHPUnit test environment for a prestashop module in a fully functional PrestasShop context.

Setting Up environment

docker-compose.yml

We use images from prestashop/docker-internal-images to instanciate a container and mount module's code.

version: "3.7"
services:
  phpunit:
    container_name: phpunit
    image: prestashop/docker-internal-images:8
    environment:
      - PS_DOMAIN=localhost
      - PS_ENABLE_SSL=0
      - PS_DEV_MODE=1
      - XDEBUG_MODE=coverage
      - XDEBUG_ENABLED=1
    volumes:
      - ./:/var/www/html/modules/ps_accounts

Makefile

Using a makefile we create a set of utility targets to start container, install module and run tests :

phpunit-pull:
	docker pull prestashop/docker-internal-images:${DOCKER_INTERNAL}

phpunit-start:
	@docker-compose up -d
	@echo phpunit started

phpunit-stop:
	@docker-compose down
	@echo phpunit stopped

phpunit-restart: phpunit-stop phpunit-start

phpunit-module-config:
	@docker exec -w ${CONTAINER_INSTALL_DIR} phpunit \
		sh -c "if [ ! -f ./config/config.yml ]; then cp ./config/config.yml.dist ./config/config.yml; fi"

phpunit-module-version:
	@docker exec -w ${CONTAINER_INSTALL_DIR} phpunit \
		sh -c "echo \"Module v\`cat config.xml | grep '<version>' | sed 's/^.*\[CDATA\[\(.*\)\]\].*/\1/'\`\n\""

phpunit-module-install: phpunit-module-config phpunit-module-version
	@docker exec phpunit sh -c "php -d memory_limit=-1 ./bin/console prestashop:module install ps_accounts"

phpunit-permissions:
	@docker exec phpunit sh -c "chown -R www-data:www-data ./var"

phpunit-run-unit: phpunit-permissions
	@docker exec -w ${CONTAINER_INSTALL_DIR} phpunit ./vendor/bin/phpunit --testsuite unit

phpunit-run-domain: phpunit-permissions
	@docker exec -w ${CONTAINER_INSTALL_DIR} phpunit ./vendor/bin/phpunit --testsuite domain

phpunit-run-feature: phpunit-permissions
	@docker exec -w ${CONTAINER_INSTALL_DIR} phpunit ./vendor/bin/phpunit --testsuite feature

phpunit-delay-5:
	@echo waiting 5 seconds
	@sleep 5

phpunit: phpunit-pull phpunit-restart phpunit-delay-5 phpunit-module-install phpunit-run-feature phpunit-run-domain phpunit-run-unit
	@echo phpunit passed

phpunit-dev: phpunit-pull phpunit-restart phpunit-delay-5 phpunit-module-install phpunit-permissions
	@echo phpunit container is ready

boostrap.php

Bootstrap PrestaShop environment in the PHPUnit boostrap file. You specify that file in the phpunit.xml file.

<?php
if (!defined('_PS_ADMIN_DIR_')) {
    define('_PS_ADMIN_DIR_', '/admin');
}

if (!defined('_PS_MODE_DEV_')) {
    define('_PS_MODE_DEV_', true);
}

$rootDirectory = getenv('_PS_ROOT_DIR_') ?: __DIR__ . '/../../..';
require_once $rootDirectory . '/config/config.inc.php';

example test

Now, you're ready to run your tests.

/**
 * @test 
 */
class IsAccountLinkedTest extends TestCase
{
    public function isShouldTestSomething()
    {
        // From here you can access anything in prestashop context 
        // get a module instance, access database entities, etc..
        
        /** @var Ps_accounts|false $module */
        $module = Module::getInstanceByName('ps_accounts');
        
        $myServiceToTest = $module->getService(MyService::class);
        
        // Your test mocks, assertions here ...
    }
}

Running tests

Using that same Makefile you can either run tests locally from command line, from your favourite IDE (aka PHPStorm) or though a GitHub Action for CI integrations

Command line

first start the container for the development tests :

make phpunit-dev

then run any test target from the makefile :

make phpunit-run-feature

or directly against docker container :

docker exec -w /var/www/html/modules/ps_accounts phpunit ./vendor/bin/phpunit --testsuite feature

Using PHPStorm

first start the container for the development tests :

make phpunit-dev

Then you just have to setup your IDE to run tests through the container.

You can do so by adding a new command line interpreter from PHPUnit configuration, selecting "from Docker".

For latest's version of PHPStorm you might have to add the following environment variable to ensure tests will run properly :

COMPOSE_INTERACTIVE_NO_CLI=true

GitHub actions

Here is an example job configuration to run your tests

jobs:
  phpunit:
    name: PHPUNIT
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Cache vendor folder
        uses: actions/cache@v3
        with:
          path: vendor
          key: php-${{ hashFiles('composer.lock') }}

      - name: Cache composer folder
        uses: actions/cache@v3
        with:
          path: ~/.composer/cache
          key: php-composer-cache

      - name: Install dependencies
        run: composer install

      - name: PHPUnit tests v8
        run: make phpunit

Benefits

Doing so you can :

  • Easily switch between PrestaShop versions (just adapt docker-compose file);
  • Mock the minimum amount of code while being in a real PrestaShop environment;
  • Run your tests in CI/CD environment as well as locally.