Using PHPUnit

From semantic-mediawiki.org
Testing
Using PHPUnit in connection with SMW
Collection
Keywords
PHPUnit · Testing · Tests · PHP
Table of Contents

Contents

Tests are commonly divided into a manual (without using any tool or automated script) and an automated scripted test approach.

Manual testing

If you want to run some manual tests (either as scripted or exploratory test procedure) then you just have to:

  1. Download a related branch using composer require "mediawiki/semantic-media-wiki:dev-foo (where foo refers to the branch name) or in case you want to test the current master, use @dev or dev-master as version together with the minimum-stability: dev flag so that the branch/master can be fetched without any stability limitations.
  2. Run composer dump-autoload to ensure that all registered classes are correctly initialized before starting any test procedure.

Automated testing (PHPUnit)

For the automated approach, Semantic MediaWiki relies on PHPUnit as scripted testing methodology. Scripted tests are used to verify that an expected behaviour occurs for codified requirements on the given conditions.

  • Unit test refers to a script that verifies results for a unit, module, or class against an expected outcome in an isolated environment
  • Integration test (or functional test) normally combines multiple components into a single process and verifies the results in a semi-production like environment (including DB access, sample data etc.)
  • System test (and its individual modules) is treated as "black-box" to observe behaviour as a whole rather than its units

Information about PHPUnit in connection with MediaWiki can be found at smw.org and mediawiki.org.

Running tests

Verify that PHPUnit is installed

> cd myMediawikiFolder
> composer show phpunit/phpunit | grep versions
versions : * 6.5.14

In case PHPUnit is not installed, run composer install --dev

Verify that your MediaWiki installation comes with its test files and folders (e.g. /myMediawikiFolder/tests ) in order for Semantic MediaWiki to have access to registered MW-core classes. If the tests folder is missing then you may follow the release source to download the missing files.

Running all tests

Run composer phpunit from the Semantic MediaWiki base directory (e.g. myMediawikiFolder/extensions/SemanticMediaWiki) using a standard command line tool which should output something like:

$ composer phpunit

Using PHP 7.2.30

Semantic MediaWiki: 3.2.0-alpha, git: abc234b
                    SMWSQLStore (postgres:9.5.10)

MediaWiki:          1.31.7, git: 42e0b35 (refs/heads/REL1_31)
                    Extension vendor autoloader

Site language:      en
Execution time:     2020-04-25 06:53

Debug logs:         Disabled
Xdebug:             Disabled (or not installed)

Intl/ICU:           1.1.0 / 52.1
PCRE:               8.41 2017-07-05

PHPUnit 6.5.14 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.2.30
Configuration: /home/travis/build/SemanticMediaWiki/mw/extensions/SemanticMediaWiki/phpunit.xml.dist

.............................................................   61 / 8526 (  0%)
.............................................................  122 / 8526 (  1%)

Note that running all tests may take a while.

Running a single testsuite

Test suites provide a way of grouping tests. Semantic MediaWiki defines a couple of testsuites in phpunit.xml.dist:

  • semantic-mediawiki-check
  • semantic-mediawiki-unit
  • semantic-mediawiki-integration
  • semantic-mediawiki-import
  • semantic-mediawiki-structure
  • semantic-mediawiki-benchmark

To run a single testsuite, use --testsuite, e.g composer phpunit -- --testsuite semantic-mediawiki-unit

Running a single test

To run a single testsuite, use --filter, e.g composer phpunit -- --filter ParserAfterTidyTest

Writing tests

Writing meaningful tests isn't difficult but requires some diligence on how to setup a test and its environment. One simple rule is to avoid the use of hidden expectations or inheritance as remedy for the "less code is good code" aesthetics. Allow the code to be readable and if possible follow the arrange, act, assert pattern.

For a short introduction on "How to write a test for Semantic MediaWiki", have a look at this video.

/tests
├─ /phpunit
│   ├─ Benchmark
│   ├─ Fixtures
│   ├─ Integration
│   │   ├─ ...
│   │   └─ JSONScript
│   ├─ Structure
│   └─ Unit
│
└─ /qunit
  • Benchmark contains collections of tests running benchmarks
  • Fixtures contains fixed data and schemata
  • Integration contains tests classified as testing the integration with MediaWiki, rely on an active DB connection, or connect to any other external service
  • Structure contains tests that verify some structural components, or not directly test a specific integration with Semantic MediaWiki or MediaWiki
  • Unit contains unit tests (those tests should not rely on an enabled MediaWiki or DB connection)

Unit tests

The use of MediaWikiTestCase is discouraged (as its binds tests and the test environment to MediaWiki) and it is best to rely on PHPUnit_Framework_TestCase and where a MW database connection is required, use the MwDBaseUnitTestCase instead.

  • QueryPrinterTestCase base class for all query and result printers
  • SpecialPageTestCase derives from SemanticMediaWikiTestCase

Integration tests

Integration tests are vital to confirm the behaviour of a component from an integrative perspective that occurs through an interplay with its surroundings.

Those tests don't replace unit tests, they complement them to verify that an expected outcome does actually occur in combination with MediaWiki and other services.

Integration tests can help reduce the recurrence of regressions or bugs, given that a developers follows a simple process:

  • Make a conjecture or hypothesis about the cause of the bug or regression
  • Find a minimal test case (using wiki text at this point should make it much easier to replicate a deviated behaviour)
  • Write a JSON test and have it fail
  • Apply a fix
  • Run the test again and then run all other integration tests to ensure nothing else was altered by accidentally introducing another regression not directly related to the one that has been fixed

The Integration directory is expected to host tests that target the validation of reciprocity with MediaWiki and/or other services such as:

  • Triple-stores (necessary for the SPARQLStore)
  • Extensions (SESP, SBL etc.)

Some details about the integration test environment can be found here.

JSONScript

One best practice in Semantic MediaWiki is to write integration tests as pseudo JSONScript to allow non-developers to review and understand the setup and requirements of its test scenarios.

The JSON format was introduced as abstraction layer to lower the barrier of understanding of what is being tested by using the wikitext markup to help design test cases quicker without the need to learn how PHPUnit or internal MediaWiki objects work.

Benchmark tests

For details, please have a look at the benchmark guide document.

JavaScript (QUnit)

Running qunit tests in connection with MediaWiki requires to execute Special:JavaScriptTest. QUnit tests are currently not executed on Travis (see #136).

Miscellaneous

See also[edit]

For details on how to setup, and run PHP unit tests, see:

For details on how to write unit tests, see: