Skip to content

Instantly share code, notes, and snippets.

@kerasai
Last active February 19, 2025 19:35
Show Gist options
  • Save kerasai/ea564bc54f3d99a6a4dda3439092051a to your computer and use it in GitHub Desktop.
Save kerasai/ea564bc54f3d99a6a4dda3439092051a to your computer and use it in GitHub Desktop.
Robo setup

Robo setup

Robo task runner setup steps, for use in Lando environment.

Require dependencies

lando composer require --dev drupal/coder \
  kerasai/robo-drupal \
  kerasai/robo-phpcs \
  mglaman/phpstan-drupal \
  phpstan/extension-installer \
  phpstan/phpstan \
  phpstan/phpstan-deprecation-rules

Add tooling to .lando.yml

tooling:
  robo:
    service: appserver
    description: Runs Robo commands
    cmd: /app/vendor/bin/robo

Basic Robofile

lando robo init

Replace Robofile.php with file below. Update to use the proper environment detection class.

Add robo.yml with file below.

Functional Testing

Setup DTT

lando composer require --dev \
  behat/mink-browserkit-driver \
  phpunit/phpunit \
  weitzman/drupal-test-traits

Add testing namespace to composer.json:

    "autoload": {
        "psr-4": {
            "MyProject\\": "src/",
            "MyProjectTests\\": "tests/"
        }
    },

Create a phpunit.xml based on https://git.drupalcode.org/project/dtt/-/blob/2.x/docs/phpunit.xml.

Set the DTT_BASE_URL environment variable in the .lando.yml:

services:
  appserver:
    overrides:
      environment:
        DTT_BASE_URL: "https://__mysite__.lndo.site"

Add Robo commands:

  /**
   * Unit tests
   */
  public function testUnit() {
    return $this->taskExec('vendor/bin/phpunit --testsuite=unit');
  }

  /**
   * Kernel tests
   */
  public function testKernel() {
    return $this->taskExec('vendor/bin/phpunit --testsuite=kernel');
  }

  /**
   * Existing site tests
   */
  public function testExistingSite() {
    return $this->taskExec('vendor/bin/phpunit --testsuite=existing-site');
  }

  /**
   * Existing site JS tests
   */
  public function testExistingSiteJavascript() {
    return $this->taskExec('vendor/bin/phpunit --testsuite=existing-site-javascript');
  }

Run DTT test commands in robo test:

    $collection->addTask($this->testUnit())
      ->addTask($this->testKernel())
      ->addTask($this->testExistingSite())
      ->addTask($this->testExistingSiteJavascript());

Add tooling to .lando.yml:

tooling:
  phpunit:
    service: appserver
    description: Runs PHPUnit
    cmd: /app/vendor/bin/phpunit

Create a test:

mkdir -p tests/src/ExistingSite
touch tests/src/ExistingSite/HomepageTest.php

Copy in the contents of HomepageTest.php below. Add the directory to the testsuite defined in phpunit.xml:

<directory>./tests/src/ExistingSite</directory>

You may also use drush to generate classes for writing tests:

drush generate test:existing or drush generate test:existing-js

<?php
use weitzman\DrupalTestTraits\ExistingSiteBase;
/**
* Test that the site loads.
*/
class HomepageTest extends ExistingSiteBase {
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
// Cause tests to fail if an error is sent to Drupal logs.
$this->failOnLoggedErrors();
}
/**
* Verify the homepage loads.
*
* @group base
*/
public function testHomepage() {
$this->drupalGet('/');
$this->assertSession()->statusCodeEquals(200);
}
}
parameters:
level: 1
paths:
- src
#- web/modules/custom
#- web/themes/custom
# Uncomment the blocks below and insert additional to add PHPCS coverage.
phpcs:
# Defaults to 'phpcs'.
path: vendor/bin/phpcs
files:
src:
standard: vendor/drupal/coder/coder_sniffer/Drupal
# tests:
# standard: vendor/drupal/coder/coder_sniffer/Drupal
# modules:
# path: web/modules/custom
# standard: vendor/drupal/coder/coder_sniffer/Drupal
# extensions: 'php,module,inc,install,test,profile,theme,css,info,txt,md'
# ignore: 'node_modules,bower_components,vendor'
# themes:
# path: web/themes/custom
# standard: vendor/drupal/coder/coder_sniffer/Drupal
# extensions: 'php,module,inc,install,test,profile,theme,info,txt,md'
# ignore: 'node_modules,bower_components,vendor,dist'
# modules_practice:
# path: web/modules/custom
# standard: vendor/drupal/coder/coder_sniffer/DrupalPractice
# extensions: 'php,module,inc,install,test,profile,theme,css,info,txt,md'
# ignore: 'node_modules,bower_components,vendor'
# themes_practice:
# path: web/themes/custom
# standard: vendor/drupal/coder/coder_sniffer/DrupalPractice
# extensions: 'php,module,inc,install,test,profile,theme,info,txt,md'
# ignore: 'node_modules,bower_components,vendor,dist'
drupal:
files:
private:
path: web/sites/default/files/private
public:
path: web/sites/default/files
<?php
use Kerasai\Robo\Config\ConfigHelperTrait;
use Kerasai\Robo\Phpcs\loadTasks;
use Kerasai\RoboDrupal\DrupalTasks;
use Robo\Robo;
use __my_project__\Env\Env;
/**
* This is project's console commands configuration for Robo task runner.
*
* @see https://robo.li/
*/
class RoboFile extends \Robo\Tasks {
use ConfigHelperTrait;
use DrupalTasks;
use loadTasks;
/**
* RoboFile constructor.
*/
public function __construct() {
$this->stopOnFail();
$this->env = Env::create();
$config_files = $this->env->getIncludes('.', 'yml', '', 'robo');
$config_files = array_filter(array_map(function ($file) {
return __DIR__ . DIRECTORY_SEPARATOR . 'robo' . DIRECTORY_SEPARATOR . $file;
}, $config_files), 'is_readable');
Robo::loadConfiguration($config_files);
}
/**
* Run PHPCBF file correction
*/
public function devPhpcbf() {
return $this->taskPhpcbf();
}
/**
* Build the project
*/
public function build() {
$collection = $this->collectionBuilder();
// Add distinct build steps here, such as `npm ci` to load dependencies for
// the theme, SASS and JS complication for the theme, and downloading
// libraries.
$this->say('Needs implemented.');
return $collection;
}
/**
* Install the application
*/
public function install() {
$collection = $this->collectionBuilder();
$collection->addTask($this->installPrepareFilesDir())
->addTask($this->installExisting())
->addTask($this->taskExec($this->getDrushCmd() . ' deploy'));
return $collection;
}
/**
* Run tests
*/
public function test() {
$collection = $this->collectionBuilder();
$collection->addTask($this->testStatic());
// If running DTT tests, also use this.
return $collection;
}
/**
* Run static tests
*/
public function testStatic() {
$collection = $this->collectionBuilder();
$collection->addTask($this->testPhpcs())
->addTask($this->testPhpstan());
return $collection;
}
/**
* PHPCS code style checks
*/
public function testPhpcs() {
return $this->taskPhpcs();
}
/**
* PHPStan analysis
*/
public function testPhpstan() {
return $this->taskExec('vendor/bin/phpstan analyse');
}
/**
* Display detected environment info
*/
public function envInfo() {
$this->say("Environment info:");
$this->say("-----------------");
foreach ($this->env->getInfo() as $key => $value) {
$this->say("$key: $value");
}
}
/**
* Display includes to be used per the environment
*/
public function envIncludes() {
$this->say("Includes:");
$this->say("---------");
foreach ($this->env->getIncludes() as $value) {
$this->say($value);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment