Automated Behavioral Testing on a budget with Pantheon, GitLab CI, and Behat

— with mparker17

Follow along at mparker17.github.io/talk–software-testing-overview

Who am I?

mparker17 on Drupal.org, GitHub, and GitLab

I work for Brady’s Meat & Deli, Digital Echidna

Brady’s Meat & Deli’s logo Digital Echidna’s logo

(previously Environment Canada, Versabanq, UWaterloo, PeaceWorks, Myplanet, OpenConcept)

Who am I? (ctd.)

I am an Acquia Certified Drupal Developer

CS degree not completed at UWaterloo

How did this all start?

  1. Bradys is using Pantheon for our existing D7 site; but we are porting our site to D8
  2. We needed to install Drupal Commerce
    • Drupal Commerce has non-Drupal dependencies, so it needs Composer
    • Using Composer on Pantheon breaks automatic updates — and isn’t encouraged

How did this all start? (ctd.)

  1. Researched other hosting providers (Acquia Cloud, Platform.sh, Omega8.cc, Contegix)
    • … for our use case, Pantheon is still cheaper by large margin
  2. Reading support pages and forums pointed me to pantheon-systems/example-drops-8-composer
    • it didn’t solve the broken automatic updates;
    • but it is a recommended way of managing a site with composer dependencies

Concept: artifact repos

By Illustratedjc - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=26761018

A photo of Kitchener’s THEMUSEUM, taken by Illustratedjc

Concept: artifact repos (ctd.)

  1. PHP is an interpreted language: its source code is the program — “traditional” languages are compiled to “artifacts”, which get distributed/run.
  1. Before D8, Drupal was in its own world: nearly everything in modules or themes
    • (sometimes you needed libraries — usually front-end scripts — and PHP libraries were a special case)
  1. This meant you could use the same Git repo to:
    • version control your source code,
    • manage the state of your production filesystem.

Concept: artifact repos (ctd.)

  1. With D8, we made a conscious decision to build on work outside Drupal community:
    • this lets us accomplish more than if we did everything ourselves…
    • but… we have to deal with Composer (which compiles dependencies);
    • and… modern theming practices often involves compiling assets.
  1. So now web dev has become more like “traditional” development (i.e.: we have to compile before we can run)

Concept: artifact repos (ctd.)

  1. Git treats artfacts like any other file
    • this is great if you’re using Git to manage the state of a filesystem,
    • but if you’re doing that, it makes development difficult (lot of noise/churn)

Concept: artifact repos (ctd.)

One possible solution:

  1. tell your VCS to ignore artifacts,
  2. do your development as normal
  3. deploy the repo to production
  4. compile your dependencies, assets, etc. on production

Concept: artifact repos (ctd.)

This has problems, though…

Concept: artifact repos (ctd.)

Set up source repo

pantheon-systems/example-drops-8-composer is a source repo template

  1. But it had a lot of stuff in it that I didn’t need (provisioning scripts, CircleCI code, etc.)
  2. And I wanted to understand it
  3. So I started by deleting all the stuff I didn’t need
    • Got it down to 32 files and 1200 lines of code (excluding composer.lock)

Set up automation bot

The automation bot needs to push code to Pantheon…

  1. Create the bot an email account
  2. Generate an SSH key pair with ssh-keygen -f $destination_file
    • Don’t forget the -f $destination_file!
    • Don’t set a password because GitLab CI can’t enter it
  3. Sign up bot for Pantheon user account; add SSH public key; generate machine token
  4. Grant the bot access to the site

Screen capture of generating an SSH key for the automation bot

Screen capture of uploading the automation bot’s SSH key

Screen capture of getting a machine token for the automation bot

Screen capture of adding the automation bot to a site’s team

Setting up GitLab CI variables

The automation bot is going to push from GitLab…

  1. Base64-encode the SSH private key with cat $destination_file | base64 -w0
  2. Add information to the GitLab repo’s Settings -> CI/CD -> Variables…
    • SSH_PRIVATE_KEY = the base64-encoded one
    • TERMINUS_ENV = dev (i.e.: the pantheon environment I want to run tests on)
    • TERMINUS_SITE = the machine name of the site
    • TERMINUS_TOKEN = the machine token

Screen capture of base64-encoding a SSH key

Screen capture of setting GitLab CI variables

GitLab CI Variable options

When entering variables, you’ll see the following options…

Behat tests

example-drops-8-composer looks for tests in tests/behat/features/

For example:

# tests/behat/features/environment_indicator.feature
Feature: Environment indicator
In order to avoid making changes to the wrong environment
As an administrator
I need a way to distinguish which environment I am using

@api
Scenario: Administrator sees links to open this page in other environments
    Given I am logged in as a user with the "administrator" role
    When I go to "admin/content"
    Then I should see "Open in: Dev"

End result

  1. When I push to a branch, GitLab CI runs in two stages…
    1. build — compiles artifact repo, pushes with SFTP to Pantheon dev site
    2. test — spawns two sub-processes that run independently
      1. test:behat — runs Behat tests on the Pantheon dev site
      2. test:code_sniff_unit_test — runs php -l, phpcs with Drupal, DrupalPractice lints, phpunit on custom code

Screen capture a successful GitLab CI pipeline

Screen capture of a successful Behat test run

Limitation: no multidev

This setup mangles the dev environment, so only one person can test, and only one change at a time; and you can’t really use the dev environment for anything else

Thanks!

Special thanks to Rob and Monica at Brady’s Meat & Deli