Example repo for writing tests in Drupal (using DDEV)

Overview

Drupal Test Writing

This is a test D9 site which can be used for practicing test writing and running. This is to be used in tandem with the Drupal Testing Crash Course training at DrupalCamp Colorado.

Download the presentation slides:

Dependencies

Note: If you want to improve performance of test running on MacOS, follow the instructions for using the new experimental mutagen functionality in Docker Desktop with DDEV-Local.

Getting Started

  1. Clone this repo locally. (Note: You may want to consider forking this repo instead of directly cloning if you wish to open pull requests)

    git clone [email protected]:WidgetsBurritos/drupal-test-writing.git

    If you run into a permission denied error with the command above, try using https instead:

    git clone https://github.com/WidgetsBurritos/drupal-test-writing.git

    Then you will need to change into that directory:

    cd drupal-test-writing
  2. Start DDEV-Local

    ddev start

    The very first time ddev start is run, it will do a few different things, which can be found in scripts/post-start.sh:

    1. Install a very simple D9 website, based on the snapshot located at snapshot/dump.sql.gz. Any subsequent ddev start runs will keep your database intact, unless you manually remove it.
    2. Install all PHP dependencies via composer.
    3. Inject a .env and phpunit.xml file in your web/core directory, based on the templates in templates/core.env and templates/core.phpunit.xml respectively. In a real project, you would want to ensure those files are handled properly and securely. See web/core/.env.example and web/core/phpunit.xml.dist for more information about those files.
    4. Install all Node.js dependencies inside the web/core directory. This is needed for nightwatch tests to run.
    5. Clear the Drupal cache.
  3. Open the site in your browser:

    ddev launch
  4. You can then use the following sample credentials to test out various roles:

    1. admin/admin - Has all the privileges
    2. bobby/bobby - Has the My Super Secret Privilege permission
    3. carol/carol - Has the Yet Another Privilege permission
    4. david/david - Has no roles or permissions set
  5. Verify everything is running properly:

    ddev composer check:everything

    If everything is working correctly, you should see a response like this:

    Attempting to load Drupal:
    ✓ Success
    Attempting to run Drupal tests:
    ✓ Success
    Attempting to run behat tests:
    ✓ Success
    Attempting to run nightwatch.js tests:
    - Connecting to chromedriver on port 9515...
    Connected to chromedriver on port 9515 (226ms).
    ✓ Success

What We're Testing

Most of what we will be working with is located in a custom module called my_testing_module.

This module is intentionally broken for the sake of demonstrating test-driven development.

This module should do the following when you navigate to /my-message:

  1. Shows a message for any authenticated users that says: "You are logged in"
    • It's actually showing "You might be logged in" instead.
  2. Shows a message for users with the my super secret privilege permission that says: "You are super special."
    • It's actually showing "You aren't all that special." instead. Well that's not very nice.
  3. Shows a message for users with the yet another privilege permission that says "You have yet another privilege."
    • This one is working as expected.
  4. If multiple scenarios apply, it should show all of the above messages.
    • It's actually only showing one of these messages.
  5. If a user is not logged in, they should get an access forbidden error.
    • It's actually showing them the message shown to authenticated users.

Labs

The following labs are available to help provide some test writing examples:

  1. Writing unit tests with PHPUnit
  2. Writing kernel tests with PHPUnit
  3. Writing system tests with PHPUnit and Nightwatch.js
  4. Writing acceptance tests with behat

Test Runners

PHPUnit (PHP Testing)

PHPUnit is a tool for testing PHP functionality in Drupal.

There are a few different ways to run PHPUnit tests. This training uses the core/scripts/run-tests.sh method, as that is what DrupalCI uses.

Run all PHPUnit tests:

If you want to run all PHPUnit-based tests for your module, you can do so with one of the following commands:

  • From inside the DDEV-Local container (i.e. after running ddev ssh):
    php core/scripts/run-tests.sh --color --verbose --sqlite /tmp/a.sqlite my_testing_module
  • From outside the DDEV-Local container:
    ddev exec php core/scripts/run-tests.sh --color --verbose --sqlite /tmp/a.sqlite my_testing_module

Note: We're using the --sqlite flag. When the test runner bootstraps Drupal, it will save results in a sqlite database, that we're just storing in the /tmp directory for now. Alternatively we could download the SimpleTest module (contrib as of D9) and use mysql DB instead.

Run specific PHPUnit tests:

Running every test, all the time, can sometimes take a while. If you want to focus on a specific test you can do so by using the --class flag instead:

  • From inside the DDEV-Local container (i.e. after running ddev ssh):
    php core/scripts/run-tests.sh --color --verbose --sqlite /tmp/a.sqlite --class 'Drupal\Tests\my_testing_module\Functional\MyFunctionalTest'
  • From outside the DDEV-Local container: (note the double-quotes on the ddev exec command)
    ddev exec "php core/scripts/run-tests.sh --color --verbose --sqlite /tmp/a.sqlite --class 'Drupal\Tests\my_testing_module\Functional\MyFunctionalTest'"

Nightwatch.js (Javascript Testing)

Nightwatch.js is a tool used for javascript testing in Drupal.

To add support for nightwatch testing in DDEV-Local, a docker-compose.chromedriver.yml file must be added into your .ddev directory.

Read Matt Glaman's Running Drupal's Nightwatch test suite on DDEV article for more information about setting this up.

Run all Nightwatch.js tests

  • From inside the DDEV-Local container (i.e. after running ddev ssh):

    cd /var/www/html/web/core
    yarn test:nightwatch ../modules/custom/my_testing_module/tests/src/Nightwatch
  • From outside the DDEV-Local container (Note: You have to specify which directory to run inside using the -d flag, and all other paths are relative to that):

    ddev exec -d /var/www/html/web/core yarn test:nightwatch ../modules/custom/my_testing_module/tests/src/Nightwatch

Run specific Nightwatch.js tests

  • From inside the DDEV-Local container (i.e. after running ddev ssh):
cd /var/www/html/web/core
yarn test:nightwatch ../modules/custom/my_testing_module/tests/src/Nightwatch/MyNightwatchTest.js
  • From outside the DDEV-Local container (Note you have to specify which directory to run inside using the -d flag, and all other paths are relative to that):
ddev exec -d /var/www/html/web/core yarn test:nightwatch ../modules/custom/my_testing_module/tests/src/Nightwatch/MyNightwatchTest.js

Behat (Behavioral Testing w/ Cucumber)

Behat is a tool for behavorial testing in Drupal.

Run all behat tests

  • From inside the DDEV-Local container (i.e. after running ddev ssh):
cd /var/www/html && behat
  • From outside the DDEV-Local container (Note you have to specify which directory to run inside using the -d flag, and all other paths are relative to that):
ddev exec -d /var/www/html behat

Run specific behat tests

  • From inside the DDEV-Local container (i.e. after running ddev ssh):
cd /var/www/html && behat features/drupal/cache.feature
  • From outside the DDEV-Local container (Note you have to specify which directory to run inside using the -d flag, and all other paths are relative to that):
ddev exec -d /var/www/html behat
Comments
  • chore(deps): Bump composer/composer from 1.10.9 to 1.10.22

    chore(deps): Bump composer/composer from 1.10.9 to 1.10.22

    Bumps composer/composer from 1.10.9 to 1.10.22.

    Release notes

    Sourced from composer/composer's releases.

    1.10.22

    • Security: Fixed command injection vulnerability in HgDriver/HgDownloader and hardened other VCS drivers and downloaders (GHSA-h5h8-pc6h-jvvx / CVE-2021-29472)

    1.10.21

    • Fixed support for new GitHub OAuth token format
    • Fixed processes silently ignoring the CWD when it does not exist

    1.10.20

    • Fixed exclude-from-classmap causing regex issues when having too many paths
    • Fixed compatibility issue with Symfony 4/5

    1.10.19

    • Fixed regression on PHP 8.0

    1.10.18

    • Allow installation on PHP 8.0

    1.10.17

    • Fixed Bitbucket API authentication issue
    • Fixed parsing of Composer 2 lock files breaking in some rare conditions

    1.10.16

    • Added warning to validate command for cases where packages provide/replace a package that they also require
    • Fixed JSON schema validation issue with PHPStorm
    • Fixed symlink handling in archive command

    1.10.15

    • Fixed path repo version guessing issue

    1.10.14

    • Fixed version guesser to look at remote branches as well as local ones
    • Fixed path repositories version guessing to handle edge cases where version is different from the VCS-guessed version
    • Fixed COMPOSER env var causing issues when combined with the global command
    • Fixed a few issues dealing with PHP without openssl extension (not recommended at all but sometimes needed for testing)

    1.10.13

    • Fixed regressions with old version validation
    • Fixed invalid root aliases not being reported

    1.10.12

    • Fixed regressions with old version validation

    1.10.11

    • Fixed more PHP 8 compatibility issues
    • Fixed regression in handling of CTRL-C when xdebug is loaded
    • Fixed status handling of broken symlinks

    1.10.10

    • Fixed create-project not triggering events while installing the root package

    ... (truncated)

    Changelog

    Sourced from composer/composer's changelog.

    [1.10.22] 2021-04-27

    • Security: Fixed command injection vulnerability in HgDriver/HgDownloader and hardened other VCS drivers and downloaders (GHSA-h5h8-pc6h-jvvx / CVE-2021-29472)

    [1.10.21] 2021-04-01

    • Fixed support for new GitHub OAuth token format
    • Fixed processes silently ignoring the CWD when it does not exist

    [1.10.20] 2021-01-27

    • Fixed exclude-from-classmap causing regex issues when having too many paths
    • Fixed compatibility issue with Symfony 4/5

    [1.10.19] 2020-12-04

    • Fixed regression on PHP 8.0

    [1.10.18] 2020-12-03

    • Allow installation on PHP 8.0

    [1.10.17] 2020-10-30

    • Fixed Bitbucket API authentication issue
    • Fixed parsing of Composer 2 lock files breaking in some rare conditions

    [1.10.16] 2020-10-24

    • Added warning to validate command for cases where packages provide/replace a package that they also require
    • Fixed JSON schema validation issue with PHPStorm
    • Fixed symlink handling in archive command

    [1.10.15] 2020-10-13

    • Fixed path repo version guessing issue

    [1.10.14] 2020-10-13

    • Fixed version guesser to look at remote branches as well as local ones
    • Fixed path repositories version guessing to handle edge cases where version is different from the VCS-guessed version
    • Fixed COMPOSER env var causing issues when combined with the global command
    • Fixed a few issues dealing with PHP without openssl extension (not recommended at all but sometimes needed for testing)

    [1.10.13] 2020-09-09

    • Fixed regressions with old version validation
    • Fixed invalid root aliases not being reported

    [1.10.12] 2020-09-08

    ... (truncated)

    Commits
    • 28c9dfb Release 1.10.22
    • cd682f9 Update xdebug-handler to latest
    • 1cdbacb Update changelog
    • 083b735 Merge pull request from GHSA-h5h8-pc6h-jvvx
    • 4dc293b Update changelog
    • 96acad1 Update github token pattern to match their latest updates
    • 54889ca Document GH token usage and also make sure we redact them in Process debug ou...
    • dc83ba9 Update GitHub token pattern
    • 06003f4 Update release step to use php8 as it produces slightly different output wrt ...
    • 812207c Merge pull request #9695 from Seldaek/avoid-invalid-dir
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • chore(deps): Bump composer/composer from 1.10.9 to 1.10.23

    chore(deps): Bump composer/composer from 1.10.9 to 1.10.23

    Bumps composer/composer from 1.10.9 to 1.10.23.

    Release notes

    Sourced from composer/composer's releases.

    1.10.23

    • Security: Fixed command injection vulnerability on Windows (GHSA-frqg-7g38-6gcf / CVE-2021-41116)

    1.10.22

    • Security: Fixed command injection vulnerability in HgDriver/HgDownloader and hardened other VCS drivers and downloaders (GHSA-h5h8-pc6h-jvvx / CVE-2021-29472)

    1.10.21

    • Fixed support for new GitHub OAuth token format
    • Fixed processes silently ignoring the CWD when it does not exist

    1.10.20

    • Fixed exclude-from-classmap causing regex issues when having too many paths
    • Fixed compatibility issue with Symfony 4/5

    1.10.19

    • Fixed regression on PHP 8.0

    1.10.18

    • Allow installation on PHP 8.0

    1.10.17

    • Fixed Bitbucket API authentication issue
    • Fixed parsing of Composer 2 lock files breaking in some rare conditions

    1.10.16

    • Added warning to validate command for cases where packages provide/replace a package that they also require
    • Fixed JSON schema validation issue with PHPStorm
    • Fixed symlink handling in archive command

    1.10.15

    • Fixed path repo version guessing issue

    1.10.14

    • Fixed version guesser to look at remote branches as well as local ones
    • Fixed path repositories version guessing to handle edge cases where version is different from the VCS-guessed version
    • Fixed COMPOSER env var causing issues when combined with the global command
    • Fixed a few issues dealing with PHP without openssl extension (not recommended at all but sometimes needed for testing)

    1.10.13

    • Fixed regressions with old version validation
    • Fixed invalid root aliases not being reported

    1.10.12

    • Fixed regressions with old version validation

    1.10.11

    • Fixed more PHP 8 compatibility issues
    • Fixed regression in handling of CTRL-C when xdebug is loaded
    • Fixed status handling of broken symlinks

    ... (truncated)

    Changelog

    Sourced from composer/composer's changelog.

    [1.10.23] 2021-10-05

    • Security: Fixed command injection vulnerability on Windows (GHSA-frqg-7g38-6gcf / CVE-2021-41116)

    [1.10.22] 2021-04-27

    • Security: Fixed command injection vulnerability in HgDriver/HgDownloader and hardened other VCS drivers and downloaders (GHSA-h5h8-pc6h-jvvx / CVE-2021-29472)

    [1.10.21] 2021-04-01

    • Fixed support for new GitHub OAuth token format
    • Fixed processes silently ignoring the CWD when it does not exist

    [1.10.20] 2021-01-27

    • Fixed exclude-from-classmap causing regex issues when having too many paths
    • Fixed compatibility issue with Symfony 4/5

    [1.10.19] 2020-12-04

    • Fixed regression on PHP 8.0

    [1.10.18] 2020-12-03

    • Allow installation on PHP 8.0

    [1.10.17] 2020-10-30

    • Fixed Bitbucket API authentication issue
    • Fixed parsing of Composer 2 lock files breaking in some rare conditions

    [1.10.16] 2020-10-24

    • Added warning to validate command for cases where packages provide/replace a package that they also require
    • Fixed JSON schema validation issue with PHPStorm
    • Fixed symlink handling in archive command

    [1.10.15] 2020-10-13

    • Fixed path repo version guessing issue

    [1.10.14] 2020-10-13

    • Fixed version guesser to look at remote branches as well as local ones
    • Fixed path repositories version guessing to handle edge cases where version is different from the VCS-guessed version
    • Fixed COMPOSER env var causing issues when combined with the global command
    • Fixed a few issues dealing with PHP without openssl extension (not recommended at all but sometimes needed for testing)

    [1.10.13] 2020-09-09

    ... (truncated)

    Commits
    • eb3bae3 Release 1.10.23
    • ca5e2f8 Fix escaping issues on Windows which could lead to command injection, fixes G...
    • 1a994e4 Update deps
    • 32eb3b4 Update deps
    • a02802b Warn 1.x users when a package is not found that it may be due to our deprecat...
    • cd682f9 Update xdebug-handler to latest
    • 1cdbacb Update changelog
    • 083b735 Merge pull request from GHSA-h5h8-pc6h-jvvx
    • 4dc293b Update changelog
    • 96acad1 Update github token pattern to match their latest updates
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Lab 4 - Add Behat Acceptance Test

    Lab 4 - Add Behat Acceptance Test

    Lab 4 continues to build on the functionality we did in #4 (notice this PR is against lab-3-functional-test, not 9.x).

    This PR adds a simple acceptance test outlining the doubles down on the security posture.

    opened by WidgetsBurritos 0
  • Lab 3 - Add Functional and Nightwatch Tests

    Lab 3 - Add Functional and Nightwatch Tests

    Lab 3 continues to build on the functionality we did in #3 (notice this PR is against lab-2-kernel-test, not 9.x).

    • In the first commit, we resolve a security issue related to permissions for /my-message.
    • In the second commit, we introduce a very simple nightwatch.js test to test toggling of a checkbox.
    • In the third commit, we do a minor refactor on the functional test, to consolidate multiple test cases into a single test case.
    opened by WidgetsBurritos 0
  • Lab 2 - Add Kernel Tests for Logger/Controller Integration

    Lab 2 - Add Kernel Tests for Logger/Controller Integration

    Lab 2 adds on to the work done in #2 (notice this PR is against lab-1-unit-test branch, not the 9.x branch) and provides kernel test coverage for the integration between with the logger/controller.

    opened by WidgetsBurritos 0
Owner
David Stinemetze
David Stinemetze
This plugin adds basic HTTP requests functionality to Pest tests, using minicli/curly

Curly Pest Plugin This plugin adds basic HTTP requests functionality to Pest tests, using minicli/curly. Installation composer require minicli/pest-pl

minicli 16 Mar 24, 2022
Mock HTTP requests on the server side in your PHP unit tests

HTTP Mock for PHP Mock HTTP requests on the server side in your PHP unit tests. HTTP Mock for PHP mocks the server side of an HTTP request to allow in

InterNations GmbH 386 Dec 27, 2022
vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. It can be used with any unit test framework, like PHPUnit or SimpleTest.

vfsStream vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. It can be used with

null 1.4k Dec 23, 2022
Some shorthand functions for skipping and focusing tests.

Pest Plugin: Shorthands This repository contains the Pest Plugin Shorthands. If you want to start testing your application with Pest, visit the main P

Thomas Le Duc 10 Jun 24, 2022
A PHP library for mocking date and time in tests

ClockMock Slope s.r.l. ClockMock provides a way for mocking the current timestamp used by PHP for \DateTime(Immutable) objects and date/time related f

Slope 44 Dec 7, 2022
Magic Test allows you to write browser tests by simply clicking around on the application being tested, all without the slowness of constantly restarting the testing environment.

Magic Test for Laravel Magic Test allows you to write browser tests by simply clicking around on the application being tested, all without the slownes

null 400 Jan 5, 2023
Wraps your Pest suite in a Laravel application instance, allowing global use of the framework in tests.

Pest Larastrap Plugin This is currently a highly experimental project and is subject to large pre-release changes. Pest PHP is an awesome PHP testing

Luke Downing 3 Jan 6, 2022
TestDummy makes the process of preparing factories (dummy data) for your integration tests as easy as possible

TestDummy TestDummy makes the process of preparing factories (dummy data) for your integration tests as easy as possible. As easy as... Build a Post m

Laracasts 461 Sep 28, 2022
A tool to run migrations prior to running tests

cakephp-test-migrator A tool to run migrations prior to running tests The Migrator For CakePHP 3.x composer require --dev vierge-noire/cakephp-test-mi

Vierge Noire 11 Apr 29, 2022
Extension to use built-in PHP server on Behat tests

Extension to use built-in PHP server on Behat tests Instalation composer require libresign/behat-builtin-extension Configuration Add the extension to

LibreSign 2 Feb 21, 2022
Enforce consistent styling for your Pest PHP tests

A set of PHP CS rules for formatting Pest PHP tests.

Worksome 2 Mar 15, 2022
Report high memory usage PHPUnit tests: Managed by opg-org-infra & Terraform

phpunit-memory-usage Report high memory usage PHPUnit tests: Managed by opg-org-infra & Terraform Configuration Add into the phpunit.xml extensions se

Ministry of Justice 2 Aug 4, 2022
Satisfy the Type APIs for the WordPress schema when running PHPUnit tests

Satisfy the Type APIs for the WordPress schema when running PHPUnit tests

GraphQL API 1 Apr 12, 2022
Prevent none-test output in your Pest tests.

Pest Plugin Silence Often, when writing tests, we echo and dump test code to debug and check everything is working correctly. It can be easy to forget

Worksome 5 Feb 23, 2022
PHP Test Generator - A CLI tool which generates unit tests

This project make usages of PHPStan and PHPParser to generate test cases for a given PHP File.

Alexander Schranz 7 Dec 3, 2022
Integrates Pest with PHP-VCR using plugins.

Pest plugin for PHP-VCR Integrates Pest with PHP-VCR using plugins. Installation You can install the package via composer: composer require phpjuice/p

PHPJuice 4 Sep 1, 2021
A video course for laravel artisan to learn creating API using testing

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Bitfumes 16 Oct 6, 2022
Implementation of PoP\Hooks using package bainternet/php-hooks

Implementation of PoP\\Hooks using package `bainternet/php-hooks` (a fork from the WordPress hooks system), to use with PHPUnit and avoid having to load WordPress

PoP 1 Jan 13, 2022