UI тесты для WordPress (Codeception + WP Browser)

UI тесты для WordPress (Codeception + WP Browser)

UI(E2E, GUI) тесты в полном объеме эмулируют поведение посетителей в браузере. Данные тесты относятся к приемочному(acceptance) виду тестирования.

Пишется пошаговый тест, как посетитель должен себя вести в приложении: на какую страницу приложения он зайдет, какую информацию заполнит, какую кнопку нажмет и т.д. Чаще всего такие тесты пишут тестировщики, но иногда и разработчики в зависимости от требований компании. В дальнейшем данные тесты можно и даже необходимо использовать как часть процесса CI(Continuous Integration).

Данный вид тестов дает 100% гарантию, что приложение работает в полном объеме начиная от сервера, бэкенда и заканчивая фронтендом. К тому же сами тесты мега-простые в написании. Звучит отлично, но как за это необходимо чем-то пожертвовать. Итак, данные тесты не показывают проблемы в коде(за исключением скриншотов, при включенном дебаге) и они слишком долго выполняются, поскольку требуют ресурсов для запуска.

Поскольку это единственные тесты, которые дают 100% гарантию работы приложения, они обязательно должны быть на любом продуктовом проекте. Даже 1 тест даст вам крутой результат, а там где 1, там и 10к тестов, которые будут запускаться пару часов, но реальные люди все равно не смогут протестировать этот же объем вручную и без ошибок.

Установка и параметр Codeception

Установим библиотеку для PHP Codeception , через которую, можно запускать практически любые виды тестов. К нему необходимо поставить дополнение WP Browser , которое поможет писать тесты для WordPress ещё проще, хотя куда ещё проще, данные тесты и так самые простые в написании.

composer require --dev codeception/codeceptioncomposer require --dev lucatume/wp-browser

Из-за того, что библиотека Codeception может запускать разные виды тестов нам понадобиться два конфига: основной и для приемочных тестов. Итак, создаем в корне приложения файл codeception.yml:

paths: tests: tests/php # директория с тестами output: codeception/_output # директория для вывода результатов запуска. В нее будут сохраняться скриншоты и HTML-страницы неудачных запусков, информация по покрытию и многое иное. data: codeception/_data        # дополнительная директорию, куда мы разместим дамп базы данных в дальнейшем.    support: codeception/_support  # директория в которую вы можете добавить любые классы(соблюдая стандарт PSR-4), которые будут загружаться при запуске тестов.    envs: codeception/_envs        # директория для конфигураций среды разработки.actor_suffix: Tester                # суффикс класса для тестеров.extensions:                         # можем подключить любые расширения.    enabled:        - Codeception\Extension\RunFailed   # расширение для продолжения работы при неудачном тесте.params:    - codeception/_config/params.php       # добавляем путь к PHP-файлу, в котором мы пропишем константы для подключения к БДsettings:                           # параметра запуска backup_globals: false           # запрещаем PHPUnit выполнять резервное копирование глобальных переменных.    colors: true                    # Делаем разноцветный отображение

Сейчас создаем конфиг для приемочных тестов tests/acceptance.suite.yml:

actor: AcceptanceTesterextensions:    enabled:        -   Codeception\Extension\RunProcess:                0: chromedriver --url-base=/wd/hub        - Codeception\Extension\RunFailed commands:        - Codeception\Command\GenerateWPUnit        - Codeception\Command\GenerateWPRestApi        - Codeception\Command\GenerateWPRestController        - Codeception\Command\GenerateWPRestPostTypeController        - Codeception\Command\GenerateWPAjax        - Codeception\Command\GenerateWPCanonical        - Codeception\Command\GenerateWPXMLRPCmodules:    enabled:        - WPDb        - WPWebDriver config:        WPDb:            dsn: 'mysql:host=%DB_HOST%;dbname=%DB_NAME%'            user: '%DB_USER%'            password: '%DB_PASSWORD%'            #import the dump before the tests; this means the test site database will be repopulated before the tests.            dump: 'codeception/_data/dump.sql'            populate: true            # re-import the dump between tests; this means the test site database will be repopulated between the tests.            cleanup: true waitlock: 10 url: '%WP_URL%'            urlReplacement: true tablePrefix: '%DB_TABLE_PREFIX%'        WPWebDriver:            url: '%WP_URL%'            port: 9515 window_size: maximize browser: chrome host: localhost adminUsername: '%WP_ADMIN_USERNAME%'            adminPassword: '%WP_ADMIN_PASSWORD%'            adminPath: '%WP_ADMIN_PATH%'            capabilities:                "goog:chromeOptions":                    args: ["--user-agent=wp-browser"]

Выглядит страшно, но в целом интуитивно понятные параметра. Если есть желание, можете разобраться с параметрами сами.

Создаем отдельную новую базу acceptance_db, ставим чистую установку WordPress, активируем тестируемый плагин/тему и делаем экспорт базы в codeception/_data/dump.sql. Можно сделать вручную или при помощи WP CLI:

wp config create --dbname="acceptance_db" --dbusroot" --dbpass="root" --dbhost="localhost" --dbprefix="wp_"wp core install --url="http://your-site.local" --title="Test" --admin_user="admin" --admin_password="pass" --admin_email="i@wp-punk.com" --skip-emailwp rewrite structure '/%postname%/' --hardwp plugin activate --allmysqldump --host="localhost" --user="root" --password="root" acceptance_db > codeception/_data/dump.sql

Создаем конфиг для подключения к БД в codeception/_config/params.php:

<?phpreturn ['WP_URL'            => 'http://your-site.local','WP_ADMIN_USERNAME' => 'admin','WP_ADMIN_PASSWORD' => 'pass','WP_ADMIN_PATH'     => '/wp-admin','DB_HOST'           => 'localhost','DB_NAME'           => 'acceptance_db','DB_USER'           => 'root','DB_PASSWORD'       => 'root','DB_TABLE_PREFIX'   => 'wp_',];

Создаем тестера, который будет выполнять наши задачи в файле codeception/_support/AcceptanceTester.php:

<?phpuse Codeception\Actor;class AcceptanceTester extends Actor {use _generated\AcceptanceTesterActions;}

Сейчас обновим wp_config.php, чтобы при запуске приемочных тестов они выполнялись на другой базе данных:

if(     isset( $_SERVER['HTTP_X_TESTING'])    ||( isset( $_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] === 'wp-browser')    || getenv( 'WPBROWSER_HOST_REQUEST')) {    define( 'DB_NAME', 'codeception_db');} else {    define( 'DB_NAME', 'local');}

С настройкой Codeception мы закончили, но… Но надо установить ChromeDriver:

  • MacOS: brew cask install chromedriver.
  • Windows: choco install chromedriver

Первый Acceptance Тест

Сейчас создаем файл tests/acceptance/FirstCest.php(Cest — суффикс по умолчанию для названия тестовых классов):

<?phpclass FirstCest {public function visitSettingsPage( AcceptanceTester $I) {$I->loginAsAdmin();$I->amOnPage( '/wp-admin/admin.php?page=plugin-name');$I->see( 'Plugin Name Settings');}}

Вот так выглядит простой тест, который можно понять и без навыков программирования. Посетитель(I) заходит какую-то страницу в админку и видит там надпись Plugin Name Settings.

Запуск тестов

vendor/bin/codecept run acceptance

При запуске, должно открыться новое окно Google Chrome, автоматом выполнить все действия, описанные в тестах и вывести результат в консоль:

UI тесты для WordPress(Codeception + WP Browser)

Как видите, самое сложное — это параметр среды, сами тесты простые и понятные без особых навыков.

Запуск приемочных тестов в GitHub Actions

Для запуска тестов надо изменить локальный сервер. Для этого создаем конфиг для Apache .github/workflows/plugin-name.conf:

<VirtualHost *:80>  DocumentRoot /home/runner/work/WPPlugin/WPPlugin/wordpress ServerName plugin-name.test ErrorLog /home/runner/work/WPPlugin/WPPlugin/logs/error.log CustomLog /home/runner/work/WPPlugin/WPPlugin/logs/access.log combined DirectoryIndex index.php index.html /index.php  <Directory /home/runner/work/WPPlugin/WPPlugin/wordpress>  DirectoryIndex index.php index.html /index.phpAllowOverride AllRequire all granted  </Directory></VirtualHost>

Сейчас необходимо как-то разделить локальный запуск и запуск во время выполнение CI в GitHub Actions. Так что меняем код в файле codeception/_config/params.php:

<?phpif( in_array( 'github-actions', $argv, true ) && file_exists( $config ) ) {// Config for GH Actions.return ['WP_URL'            => 'http://plugin-name.test','WP_ADMIN_USERNAME' => 'admin','WP_ADMIN_PASSWORD' => 'admin','WP_ADMIN_PATH'     => '/wp-admin','DB_HOST'           => '127.0.0.1','DB_NAME'           => 'test_db','DB_USER'           => 'user','DB_PASSWORD'       => 'passw0rd','DB_TABLE_PREFIX'   => 'wp_',];}return ['WP_URL'            => 'http://your-site.local','WP_ADMIN_USERNAME' => 'admin','WP_ADMIN_PASSWORD' => 'pass','WP_ADMIN_PATH'     => '/wp-admin','DB_HOST'           => 'localhost','DB_NAME'           => 'acceptance_db','DB_USER'           => 'root','DB_PASSWORD'       => 'root','DB_TABLE_PREFIX'   => 'wp_',];

Создаем конфиг для GH Actions .github/workflows/plugin-name.yml :

name: PluginName GitHub Actionson: [push]jobs:    build:        strategy:            matrix:                php-versions: [7.4]        runs-on: ubuntu-latest env:            php-ext-cache-key: cache-v1 # can be any string, change to clear the extension cache.            php-extensions: mysql php-ini-values: post_max_size=256M wp-directory: wordpress wp-plugins-directory: wordpress/wp-content/plugins DB_HOST: 127.0.0.1 DB_TABLE_PREFIX: wp_            DB_NAME: test_db DB_USER: user DB_PASSWORD: passw0rd WP_URL: http://plugin-name.test WP_DOMAIN: plugin-name.test WP_ADMIN_USERNAME: admin WP_ADMIN_PASSWORD: admin WP_ADMIN_EMAIL: admin@plugin-name.test services:            mysql:                image: mysql:5.6 env:                    MYSQL_USER: ${{ env.DB_USER }}                    MYSQL_PASSWORD: ${{ env.DB_PASSWORD }}                    MYSQL_DATABASE: ${{ env.DB_NAME }}                    MYSQL_ALLOW_EMPTY_PASSWORD: yes ports:                    - 3306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps:            -   name: Download Plugin uses: actions/checkout@v2 with:                    path: ${{ env.wp-plugins-directory }}            -   name: Install dependencies working-directory: ${{ env.wp-plugins-directory }}                run: |                    composer install yarn install            -   name: Setup PHP uses: shivammathur/setup-php@v2 with:                    tools: pecl php-version: ${{ matrix.php-versions }}                    extensions: ${{ env.php-extensions }}                    ini-values: ${{ env.php-ini-values }}                env:                    update: true            -   name: Install WP CLI run: |                    curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar chmod +x wp-cli.phar mkdir -p wp-cli sudo mv wp-cli.phar wp-cli/wp echo "::add-path::$GITHUB_WORKSPACE/wp-cli"                    echo -n "apache_modules:\n  - mod_rewrite" > "${{ env.wp-directory }}/wp-cli.yml"            -   name: Install WP working-directory: ${{ env.wp-directory }}                run: |                    wp core download --version=5.4 wp config create --dbname="${{ env.DB_NAME }}" --dbuser="${{ env.DB_USER }}" --dbpass="${{ env.DB_PASSWORD }}" --dbhost="${{ env.DB_HOST }}" --dbprefix="${{ env.DB_TABLE_PREFIX }}"                    wp core install --url="${{ env.WP_URL }}" --title="Test" --admin_user="${{ env.WP_ADMIN_USERNAME }}" --admin_password="${{ env.WP_ADMIN_PASSWORD }}" --admin_email="${{ env.WP_ADMIN_EMAIL }}" --skip-email wp rewrite structure '/%postname%/' --hard wp plugin activate --all            -   name: Make a DB dump for Codeception working-directory: ${{ env.wp-plugins-directory }}                run: mysqldump --host="${{ env.DB_HOST }}" --user="${{ env.DB_USER }}" --password="${{ env.DB_PASSWORD }}" ${{ env.DB_NAME }} > codeception/_data/dump.sql            -   name: Setup hosts run: |                    echo ${{ env.DB_HOST }} ${{ env.WP_DOMAIN }} | sudo tee -a /etc/hosts cat /etc/hosts            -   name: Install & configure Apache run: |                    sudo add-apt-repository ppa:ondrej/php sudo apt-get update sudo apt-get install apache2 libapache2-mod-php7.4 mkdir -p logs sudo cp ${{ env.wp-plugins-directory }}/.github/workflows/plugin-name.conf /etc/apache2/sites-available/plugin-name.conf sudo a2enmod headers sudo a2enmod rewrite sudo a2ensite plugin-name sudo service apache2 restart            -   name: Setup Chromedriver uses: nanasess/setup-chromedriver@master            -   name: Run Chromedriver run: |                    export DISPLAY=:99 chromedriver --url-base=/wd/hub &                    sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &amp; # optional            -   name: Run Acceptance Tests working-directory: ${{ env.wp-plugins-directory }}                run: .vendor/bin/composer acceptance -- --env github-actions            -   name: Archive Codeception output uses: actions/upload-artifact@v1 if: failure()                with:                    name: codeception-output path: ${{ env.wp-plugins-directory }}/codeception/_output            -   name: Archive Apache Logs uses: actions/upload-artifact@v1 if: failure()                with:                    name: apache-logs path: logs

Сейчас, при добавлении нового кода в репозиторий, автоматом запускаются приемочные тесты.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *