Skip to content

Test Magento modules installation

Maksym Zaporozhets edited this page Jan 8, 2024 · 2 revisions

magento:test-module-install

Refresh module files and reinstall Magento 2 application.

Description

Test installing modules on the existing Magento 2 instance. Use the command from the Magento root directory.

Usage

The common flow is to install Sample Data, reinstall Magento, and install module(s):

php "${DOCKERIZER_PROJECTS_ROOT_DIR}dockerizer_for_php/bin/dockerizer" magento:test-module-install \
    /directory/with/module(s) \
    /another/directory/with/module(s)

CI/CD-like flow is to install Sample Data, copy module(s) inside Magento, reinstall Magento: add --togerther option (like "Hey, install my module(s) together with installing Magento").

Command arguments and options

  • module-directories (required, multiple): Directory with Magento 2 modules.
  • -t (--together, optional): Copy module files before running the magento:setup command.

How it works

  1. Validate Magento and modules: ensure Magento is running; get the modules list by searching for the etc/module.xml files.
  2. Install Sample Data modules if missed. Do not run setup:upgrade.
  3. Clean up Magento 2, reinstall it, and handle --together option.
  4. Final switch to production mode.
  5. Commit changes for easy identification of the module code changes.

Remember that all files are copied, disregarding the .gitignore or any other limitations.

How to test modules

Developing Magento modules requires testing them for compatibility with multiple Magento versions. Do the following:

  • Install multiple Magento versions with the magento:setup command.
  • Develop the module under the oldest supported Magento version (this works much better than implementing such support later).
  • Go to the directory containing another Magento instance and run this command.

Thus, you can open several terminal windows with different Magento versions and run installing/refreshing module(s) on all of them with a single command (or alias). After that, you can run unit or functional tests or perform other operations.

Be sure to test the module both with and without the --together option. It may unveil various indexation, code compilation, or other issues in your module(s).

Integrate these checks in your CI/CD pipelines. You can create pre-built containers with several Magento versions to speed up the pipelines.

Always use Docker compositions that include Varnish to develop and test your modules. This helps avoid caching issues, build a proper module architecture, and properly deal with the Private content.

Executes other commands

Appendix A: Test module upgrade and fresh installation

Run from the Magento root directory:

#!/bin/bash

set -e

CURRENT_DIRECTORY=${PWD##*/}

if [ ! -f ./app/etc/env.php ]; then
    echo "No env.php file found. Please run this script from the root of your Magento 2 installation."
    exit 1
fi

# Clean log files
> var/log/apache_error.log || true
> var/log/system.log || true
> var/log/exception.log || true

printf '\n>>> First install the previous module version.'
php -d xdebug.start_with_request=trigger "${DOCKERIZER_PROJECTS_ROOT_DIR}dockerizer_for_php/bin/dockerizer" magento:test-module-install /path/to/the/previous_module_version/

printf '\n>>> Copy newer module files from another directory'
rm -rf ./app/code/Vendor/* ./generated/code/* ./generated/metadata/*
cp -r /path/to/the/latest_module_code/Vendor/* ./app/code/Vendor/

printf '\n>>> Run run "setup:upgrade" to guarantee the module upgradability'
docker exec -it "${CURRENT_DIRECTORY}"-apache-prod php bin/magento setup:upgrade

printf '\n>>> Switch to production mode and run reindex'
docker exec -it "${CURRENT_DIRECTORY}"-apache-prod php bin/magento deploy:mode:set production
docker exec -it "${CURRENT_DIRECTORY}"-apache-prod php bin/magento indexer:reindex

printf '\n>>> Reinstall Magento and install the module after that'
php -d xdebug.start_with_request=trigger "${DOCKERIZER_PROJECTS_ROOT_DIR}dockerizer_for_php/bin/dockerizer" magento:test-module-install /path/to/the/latest_module_code/

printf '\n>>> Reinstall Magento with the module files included'
php -d xdebug.start_with_request=trigger "${DOCKERIZER_PROJECTS_ROOT_DIR}dockerizer_for_php/bin/dockerizer" magento:test-module-install --together /path/to/the/latest_module_code/

You can also write a PHP script to do this for you within multiple Magento instances. It is a good idea to add it to the module repository.

Appendix B: A simple PHP script for testing modules

The below PHP script runs the Appendix A script for multiple Magento instances.

ATTENTION! The script contains a hardcode! Replace:

  • /user/ with your Linux username (or improve the script to get it automatically)
  • module- with your module name or tag. It must be unique to avoid conflicts with the same scripts for other modules
  • cp /home/user/misc/apps/module/tests/test_module_upgrade.sh with the path to the Appendix A script (probably stored somewhere in the module repository)
  • Check the $magentoVersions array to ensure it contains your desired Magento versions.
<?php

declare(strict_types=1);

class InstallAndTest
{
    private const DOCKERIZER = '/home/user/misc/apps/dockerizer_for_php/bin/dockerizer';

    // cd /home/user/misc/apps/module/tests/
    private $magentoVersions = [
        // php install_and_test.php module-232-71.local
        'module-232-71.local' => [
            'magento' => '2.3.2',
            'template' => 'magento_2.3.1-2.3.2_nginx_varnish_apache',
            'required-services' => 'nginx_latest,varnish_4,php_7_1_apache,mariadb_10_1_persistent',
            'optional-services' => 'elasticsearch_5_6_16_persistent'
        ],
        // php install_and_test.php module-232-72.local
        'module-232-72.local' => [
            'magento' => '2.3.2',
            'template' => 'magento_2.3.1-2.3.2_nginx_varnish_apache',
            'required-services' => 'nginx_latest,varnish_4,php_7_2_apache,mariadb_10_2_persistent',
            'optional-services' => 'elasticsearch_5_6_16_persistent'
        ],
        // php install_and_test.php module-237p3-74.local
        'module-237p3-74.local' => [
            'magento' => '2.3.7-p3',
            'template' => 'magento_2.3.7-p3_nginx_varnish_apache',
            'required-services' => 'nginx_latest,varnish_6_5_1,php_7_4_apache,mysql_5_7_persistent',
            'optional-services' => 'elasticsearch_7_16_3_persistent'
        ],
        // php install_and_test.php module-240-73.local
        'module-240-73.local' => [
            'magento' => '2.4.0',
            'template' => 'magento_2.4.0_nginx_varnish_apache',
            'required-services' => 'nginx_latest,varnish_6_2_1,php_7_3_apache,mysql_5_7_persistent,elasticsearch_7_6_2_persistent'
        ],
        // php install_and_test.php module-240-74.local
        'module-240-74.local' => [
            'magento' => '2.4.0',
            'template' => 'magento_2.4.0_nginx_varnish_apache',
            'required-services' => 'nginx_latest,varnish_6_2_1,php_7_4_apache,mariadb_10_4_persistent,elasticsearch_7_6_2_persistent'
        ],
        // php install_and_test.php module-243p2-74.local
        'module-243p2-74.local' => [
            'magento' => '2.4.3-p2',
            'template' => 'magento_2.4.3-p2_nginx_varnish_apache',
            'required-services' => 'nginx_latest,varnish_6_5_1,php_7_4_apache,mariadb_10_4_persistent,elasticsearch_7_16_3_persistent'
        ],
        // php install_and_test.php module-244-81.local
        'module-244-81.local' => [
            'magento' => '2.4.4',
            'template' => 'magento_2.4.4_nginx_varnish_apache',
            'required-services' => 'nginx_latest,varnish_7_0,php_8_1_apache,mysql_8_0_persistent,elasticsearch_7_16_3_persistent'
        ],
        // php install_and_test.php module-245-81.local
        'module-245-81.local' => [
            'magento' => '2.4.5',
            'template' => 'magento_2.4.5_nginx_varnish_apache',
            'required-services' => 'nginx_latest,varnish_7_0,php_8_1_apache,mysql_8_0_persistent,elasticsearch_7_17_5_persistent'
        ]
    ];

    public function __invoke()
    {
        if (isset($_SERVER['argv'][1])) {
            $this->run($_SERVER['argv'][1]);
        } else {
            foreach (array_keys($this->magentoVersions) as $domain) {
                $this->run($domain);
            }
        }
    }

    private function run(string $domain): void
    {
        $info = $this->magentoVersions[$domain];
        $installationCommand = sprintf(
            'php -d xdebug.start_with_request=trigger %s magento:setup %s --domains="%s www.%s" --template=%s --required-services=%s -n -f',
            self::DOCKERIZER,
            $info['magento'],
            $domain,
            $domain,
            escapeshellarg($info['template']),
            escapeshellarg($info['required-services'])
        );

        if (isset($info['optional-services'])) {
            $installationCommand .= ' --optional-services=' . escapeshellarg($info['optional-services']);
        }

        $this->passthru($installationCommand, true);
        $projectRoot = "/home/user/misc/apps/$domain/";

        if (!chdir($projectRoot)) {
            throw new \RuntimeException('Can\'t chdir to ' . $projectRoot);
        }

        $this->passthru('cp /home/user/misc/apps/module/tests/test_module_upgrade.sh ./');
        $this->passthru('sh ./test_module_upgrade.sh');

        // Shutdown and remove containers
        $dockerComposeFilesPath = sprintf('%s.dockerizer/%s-prod/', $projectRoot, $domain);

        if (!chdir($dockerComposeFilesPath)) {
            throw new \RuntimeException('Can\'t chdir to ' . $dockerComposeFilesPath);
        }

        $this->passthru('docker-compose -f docker-compose.yaml -f docker-compose-dev-tools.yaml down --volumes --remove-orphans');
        $this->passthru("rm -rf $projectRoot");
    }

    /**
     * @param string $command
     * @param bool $allowFail
     * @return void
     */
    private function passthru(string $command, bool $allowFail = false): void
    {
        $result = 0;
        passthru($command, $result);

        if ($result && !$allowFail) {
            exit($result);
        }
    }
}

(new InstallAndTest())();

Run the PHP script:

cd /home/user/misc/apps/module/tests/
# Run for all Magento versions
php InstallAndTest.php
# Run for a specific Magento version
php InstallAndTest.php module-245-81.local
Clone this wiki locally