Skip to content

Commit

Permalink
[BWP-96] Add support for running integration tests
Browse files Browse the repository at this point in the history
Using the WP-PHPUnit framework we can run integration tests with WP - this test suite will spin up a working version of WP and run the tests.
  • Loading branch information
jdamner committed Oct 16, 2024
1 parent 56d7940 commit 27b48b9
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 10 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/tests-php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ jobs:
test:
name: PHP Tests
runs-on: ubuntu-latest
services:
database:
image: mariadb:10.11.9
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -44,3 +53,11 @@ jobs:
- name: Run PHPUnit
run: composer phpunit
continue-on-error: ${{ matrix.required == 'optional' }}
- name: Run PHP Integration Tests
run: composer phpintegration
continue-on-error: ${{ matrix.required == 'optional' }}
env:
DB_NAME: wordpress
DB_USER: root
DB_PASSWORD: root
DB_HOST: database
10 changes: 9 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9",
"szepeviktor/phpstan-wordpress": "^1.3",
"wp-phpunit/wp-phpunit": "^6.6",
"yoast/phpunit-polyfills": "^2"
},
"extra": {
Expand Down Expand Up @@ -122,7 +123,14 @@
"phpcs": "phpcs",
"phpcbf": "phpcbf",
"phpstan": "phpstan analyse --memory-limit=1G",
"phpunit": "phpunit --coverage-html ./coverage/phpunit"
"phpunit": "phpunit --coverage-html ./coverage/phpunit",
"phpintegration": "phpunit -c phpintegration.xml.dist --coverage-html ./coverage/phpintegration",
"test": [
"@phpunit",
"@phpintegration",
"@phpstan",
"@phpcs"
]
},
"minimum-stability": "dev",
"prefer-stable": true
Expand Down
50 changes: 49 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions docs/dev/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,26 @@ Testing WordPress sites can be a challenge. We should strive to make use of diff

## Unit Testing

Unit tests should be added for every `(mu-)plugin`/`theme` we create. We should always aim to decouple the core logic from WordPress, for this to be true we should avoid any use of global functions or hidden dependencies in any classes/functions we use for our core logic. We should then be able to unit test these easily.
Unit tests should test _your_ code decoupled and independent the core logic from WordPress. For this to be true we should avoid any use of global functions or hidden dependencies in any classes/functions we use for our core logic. We should then be able to unit test these easily.

We use [PHPUnit](https://phpunit.de/) for unit testing.
We use [WP_Mock](https://github.com/10up/wp_mock) to help mock some WP core functions, with [PHPUnit](https://phpunit.de/) as the test runner.

## Integration Testing

Integration tests should also be added wherever appropriate. For any part of your `(mu-)plugin`/`theme` that interacts with WordPress this should be covered by an integration test.
Integration tests should test where your code depends on intergration with other codebases, including WordPress _or_ other plugins.

We also use [PHPUnit](https://phpunit.de/) for integration testing along with [WP PHPUnit](https://github.com/wp-phpunit/wp-phpunit) which will allow you to interact with the WordPress install easily. It also provides a number of helpers to allow for easy generation of synthetic data for testing.

### Running the unit & integration tests
### Running the unit tests

Both the unit tests and integration tests follow the same structure, tests are designed to be added within each `mu-plugin` you create within a `tests` directory. The test runner sits outside though in the root of this repo. It works by looping over each `mu-plugin` and running its test.
Unit tests are should live within each `mu-plugin` in a `tests` directory.
Integration tests are to be stored in `/tests/integration` though it would be sensible to structure this folder with names consistent with the class under test.

> It's important each `mu-plugin` follows the format `plugin-name/plugin-name.php`

`bin/docker/phpunit`
`bin/docker/composer run phpunit`
`bin/docker/composer run phpintegration`

(or `bin/phpunit` if not using docker)
(or `composer run phpunit` if not using docker)

## Visual Regression Testing

Expand Down
28 changes: 28 additions & 0 deletions phpintegration.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<phpunit
bootstrap="tests/phpintegration-bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
beStrictAboutTestsThatDoNotTestAnything="true"
beStrictAboutOutputDuringTests="true"
>
<php>
<env name="WP_PHPUNIT__TESTS_CONFIG" value="tests/phpintegration-wp-config.php" />
</php>
<testsuites>
<testsuite name="Integration Tests">
<directory suffix=".php">tests/integration</directory>
</testsuite>
</testsuites>
<coverage>
<include>
<directory suffix=".php">./wp-content/mu-plugins</directory>
<directory suffix=".php">./wp-content/themes</directory>
</include>
<exclude>
<directory suffix=".php">./wp-content/mu-plugins/vendor</directory>
</exclude>
</coverage>
</phpunit>
2 changes: 2 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ parameters:
- 'wp-content/mu-plugins/*/Tests/*.php'
- 'wp-content/db.php'
- 'wp-content/object-cache.php'
- 'wp/wp-admin/includes/noop.php'
- 'wp-content/client-mu-plugins/vendor/10up/wp_mock'
analyse:
- wp-content/mu-plugins/flagpole
- wp-content/mu-plugins/wp-hook-attributes
Expand Down
22 changes: 22 additions & 0 deletions tests/integration/SampleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Sample Test
*
* @package BoxUk
*/

declare( strict_types=1 );

namespace BoxUk\Tests\Integration;

use WP_UnitTestCase;

/**
* Sample test case.
*/
class SampleTest extends WP_UnitTestCase {

public function test_sample() {
$this->assertTrue( true );
}
}
15 changes: 15 additions & 0 deletions tests/phpintegration-bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Bootstrap the WordPress tests.
*/

declare ( strict_types=1 );

$root = dirname( __DIR__ );
$composer = json_decode( file_get_contents( $root . '/composer.json' ), true, 512, JSON_THROW_ON_ERROR );
$vendor = $composer['config']['vendor-dir'];
$tests_dir = getenv( 'WP_PHPUNIT__DIR' );

require_once $vendor . '/autoload.php';
require_once $tests_dir . '/includes/functions.php';
require_once $tests_dir . '/includes/bootstrap.php';
42 changes: 42 additions & 0 deletions tests/phpintegration-wp-config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare ( strict_types=1 );

use Symfony\Component\Dotenv\Dotenv;

$root = dirname( __DIR__ );
$composer = json_decode( file_get_contents( $root . '/composer.json' ), true, 512, JSON_THROW_ON_ERROR );
$vendor = $composer['config']['vendor-dir'];

require_once $vendor . '/autoload.php';

if ( is_readable( $root . '/.env' ) ) {
$dotenv = new Dotenv();
$dotenv->usePutenv( true );
$dotenv->load( $root . '/.env' );
}

/* DB */
define( 'DB_NAME', $_ENV['DB_NAME'] ?? 'wordpress' );
define( 'DB_USER', $_ENV['DB_USER'] ?? 'root' );
define( 'DB_PASSWORD', $_ENV['DB_PASSWORD'] ?? 'root' );
define( 'DB_COLLATE', $_ENV['DB_COLLATE'] ?? 'utf8mb4_unicode_ci' );
define( 'DB_HOST', $_ENV['DB_HOST'] ?? '127.0.0.1' );
$table_prefix = 'wptests_'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited

/* WP */
define( 'WP_DEBUG', true );
define( 'SCRIPT_DEBUG', true );
define( 'ABSPATH', $root . '/wp/' );
define( 'WP_CONTENT_DIR', $root . '/wp-content' );
define( 'WP_DEFAULT_THEME', 'default' );
define( 'WP_ENVIRONMENT_TYPE', 'development' );
define( 'WP_TESTS_DOMAIN', 'tests.boxuk.com' );
define( 'WP_TESTS_EMAIL', '[email protected]' );
define( 'WP_TESTS_TITLE', 'Test Blog' );
define( 'WP_PHP_BINARY', 'php' );
define( 'PROJECT_NAME', 'boxuk' );

if (file_exists($root . '/wp-content/vip-config/vip-config.php')) {
require_once($root . '/wp-content/vip-config/vip-config.php');
}

0 comments on commit 27b48b9

Please sign in to comment.