devel:unittesting
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
devel:unittesting [2014-06-05 03:04] – [Integration Tests] Typo. samwilson | devel:unittesting [2024-03-09 23:41] (current) – fix xref 2001:9e8:18f1:9e00:a2af:9ad3:e886:2a5b | ||
---|---|---|---|
Line 5: | Line 5: | ||
DokuWiki' | DokuWiki' | ||
- | We use the [[http:// | + | We use the [[http:// |
===== Setup ===== | ===== Setup ===== | ||
+ | Install the needed requirements using [[composer]]: | ||
- | ==== Requirements ==== | ||
- | |||
- | * PHPUnit 3.6.10+ http:// | ||
- | * PHP 5.3+ http:// | ||
- | |||
- | ==== PHPUnit Installation ===== | ||
- | |||
- | === via PEAR installer === | ||
- | |||
- | pear config-set auto_discover 1 | ||
- | pear install pear.phpunit.de/ | ||
- | |||
- | === via Composer === | ||
- | |||
- | Include a composer.json file in your project, which can be as minimal as: | ||
< | < | ||
- | { | + | cd dokuwiki/_test |
- | " | + | composer install |
- | " | + | |
- | } | + | |
- | } | + | |
</ | </ | ||
- | |||
- | === via PHP archive (PHAR) === | ||
- | |||
- | Download https:// | ||
===== Running Tests ===== | ===== Running Tests ===== | ||
Line 45: | Line 24: | ||
Just change to the '' | Just change to the '' | ||
- | | + | < |
- | | + | cd _test/ |
+ | composer run test | ||
+ | </ | ||
- | PHPUnit will fail on some systems with a //headers already sent// error. | + | ==== Single Test Files ==== |
- | This is a known problem with PHPUnit, the error can be avoided by passing the | + | |
- | ' | + | |
- | phpunit --stderr | + | You can run a specific test file by giving it as a parameter: |
+ | cd _test | ||
+ | composer run test tests/ | ||
- | ==== Selected | + | ==== Grouped |
- | You can run a single test file by providing it as an argument to phpunit: | + | You include or exclude tests by their group: |
- | phpunit | + | <code bash> |
+ | cd _test | ||
+ | # run all tests that require an internet connection | ||
+ | composer run test -- --group internet | ||
+ | # run all tests that don't require an internet connection | ||
+ | composer run test -- --exclude-group internet | ||
+ | </ | ||
- | You can also use groups to exclude certain test from running. For example use | + | Note the ''< |
- | the following command to avoid long running | + | |
- | Internet. | + | |
- | phpunit --stderr --exclude-group slow, | + | ==== Plugins ==== |
+ | Plugins tests are tagged with a group named '' | ||
+ | |||
+ | <code bash> | ||
+ | cd _test | ||
+ | composer run test -- --group plugin_extension | ||
+ | </ | ||
+ | |||
+ | Note the ''< | ||
+ | |||
+ | Please note that some plugins may require other plugins in order to pass, either as dependencies, | ||
===== Writing Tests ===== | ===== Writing Tests ===== | ||
PHPUnit makes writing new tests as painless as possible. In general it means writing a fairly simple PHP class and placing it in the right directory with the right file name. Once that's done, the test can immediately be executed as explained above. | PHPUnit makes writing new tests as painless as possible. In general it means writing a fairly simple PHP class and placing it in the right directory with the right file name. Once that's done, the test can immediately be executed as explained above. | ||
- | |||
For a general overview on how to write unit tests refer to the [[http:// | For a general overview on how to write unit tests refer to the [[http:// | ||
Line 77: | Line 71: | ||
==== Naming Conventions ==== | ==== Naming Conventions ==== | ||
- | Tests are placed somewhere below the '' | + | Every new bit of code should follow [[https:// |
- | All tests need to end in '' | + | In accordance ẃith PHPUnit conventions test classes should |
+ | |||
+ | This means a class '' | ||
+ | |||
+ | Each test class need to inherit from [[xref>_test/core/DokuWikiTest.php|\DokuWikiTest]]. A test class can have multiple test functions, each prefixed with '' | ||
+ | |||
+ | |||
+ | For legacy, functional code no namespace is used. Tests are located in the sub directories | ||
- | Each test file has to contain one < | ||
==== Environment ==== | ==== Environment ==== | ||
Line 98: | Line 98: | ||
Additionally the test suite runs a '' | Additionally the test suite runs a '' | ||
- | * reload the dokuwiki | + | * reload the DokuWiki |
* reload the plugin controller and plug-ins | * reload the plugin controller and plug-ins | ||
* reload the event handler | * reload the event handler | ||
- | * ensure | + | * ensure |
- | * ensure | + | * ensure |
* reload global variables like '' | * reload global variables like '' | ||
^ //Note:// Remember to call '' | ^ //Note:// Remember to call '' | ||
- | There is no real process isolation between all tests, each test class should have a pretty clean DokuWiki environment to work on. This also includes DokuWiki' | + | Even though there is no real process isolation between all tests, each test class should have a pretty clean DokuWiki environment to work on. This also includes DokuWiki' |
+ | |||
+ | To clean up and reset the remainder of a test, the methods '' | ||
==== Integration Tests ==== | ==== Integration Tests ==== | ||
Line 131: | Line 134: | ||
The request variables are set via setter methods and look like: | The request variables are set via setter methods and look like: | ||
+ | |||
^ Variable | ^ Variable | ||
| '' | | '' | ||
Line 138: | Line 142: | ||
- | Finally you have to execute the request. This can be done by calling the '' | + | Finally you have to execute the request. This can be done by calling the '' |
+ | <code php> | ||
+ | $response = $request-> | ||
+ | </ | ||
- | Additionally there are two methods for '' | + | Additionally there are two methods for '' |
<code php> | <code php> | ||
// a get request | // a get request | ||
- | $request-> | + | $response = $request-> |
// a post request | // a post request | ||
- | $request-> | + | $response = $request-> |
</ | </ | ||
Line 155: | Line 162: | ||
As mentioned the requests are not real requests. Every call you make in your test changes the behavior of DokuWiki on the request. | As mentioned the requests are not real requests. Every call you make in your test changes the behavior of DokuWiki on the request. | ||
- | Here this is used to hook a event. | + | Here this is used to hook an event |
<code php> | <code php> | ||
- | function testHookTriggering() { | + | public |
+ | { | ||
global $EVENT_HANDLER; | global $EVENT_HANDLER; | ||
Line 179: | Line 187: | ||
</ | </ | ||
- | === Example: Using phpQuery | + | === Example: Using php-dom-wrapper |
Sometimes you want to inspect the resulting html of a request. | Sometimes you want to inspect the resulting html of a request. | ||
- | To provide a little comfort we use the [[http://code.google.com/p/phpquery/|phpQuery]] library. | + | To provide a little comfort we use the [[https://github.com/scotteh/php-dom-wrapper|php-dom-wrapper]] library. |
- | With this you can use operate in a jQuery like style on the html. | + | |
- | A simple | + | With this you can operate in a jQuery like style on the returned HTML. |
+ | |||
+ | Two simple | ||
<code php> | <code php> | ||
- | function testSimpleRun() { | + | public |
+ | { | ||
// make a request | // make a request | ||
$request = new TestRequest(); | $request = new TestRequest(); | ||
Line 193: | Line 203: | ||
// get the generator name from the meta tag. | // get the generator name from the meta tag. | ||
- | $generator = $response-> | + | $generator = $response-> |
- | + | | |
// check the result | // check the result | ||
$this-> | $this-> | ||
} | } | ||
</ | </ | ||
+ | |||
+ | <code php> | ||
+ | public function testPageContent() | ||
+ | { | ||
+ | // make a request | ||
+ | $request = new TestRequest(); | ||
+ | $response = $request-> | ||
+ | |||
+ | // search your html | ||
+ | $links = $response-> | ||
+ | $countLinks = $links-> | ||
+ | |||
+ | // check the result | ||
+ | $this-> | ||
+ | } | ||
+ | </ | ||
+ | |||
==== Plugin and Template Tests ==== | ==== Plugin and Template Tests ==== | ||
- | Sometime you need unit tests in your extensions((extensions are plug-ins and templates)). Here you can use the same classes and methods as used in the DokuWiki core. The plugin wizard has an option to add an example test in your plugin skeleton. | + | Sometime you need unit tests in your extensions((extensions are plug-ins and templates)). Here you can use the same classes and methods as used in the DokuWiki core. The plugin wizard has an option to add an example test in your plugin skeleton. Alternatively you can use the [[plugin: |
- | Just put your tests under the ''< | + | Just put your tests under the ''< |
To work, your plugin needs to be enabled during the test. This is done by putting it and all plugins it depends on in the '' | To work, your plugin needs to be enabled during the test. This is done by putting it and all plugins it depends on in the '' | ||
Line 218: | Line 246: | ||
* @group plugins | * @group plugins | ||
*/ | */ | ||
- | class helper_plugin_data_test extends DokuWikiTest { | + | class helper_plugin_data_test extends DokuWikiTest |
+ | { | ||
- | protected $pluginsEnabled = array(' | + | protected $pluginsEnabled = [' |
public static function setUpBeforeClass(){ | public static function setUpBeforeClass(){ | ||
parent:: | parent:: | ||
// copy our own config files to the test directory | // copy our own config files to the test directory | ||
- | TestUtils:: | + | TestUtils:: |
} | } | ||
public function testExample() { | public function testExample() { | ||
- | $this-> | + | $this-> |
} | } | ||
} | } | ||
</ | </ | ||
- | Plugin authors are encouraged | + | A plugin' |
+ | |||
+ | <code php> | ||
+ | public function setUp() | ||
+ | { | ||
+ | global $conf; | ||
+ | |||
+ | parent:: | ||
+ | |||
+ | $conf[' | ||
+ | $conf[' | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | So the correct indexing for plugins is '' | ||
+ | |||
+ | ===== Continous Integration with Github Actions ===== | ||
+ | |||
+ | |||
+ | Plugin authors are encouraged | ||
+ | |||
+ | ==== Requirements ==== | ||
+ | FIXME update | ||
+ | |||
+ | If your tests require additional plugins to be installed, provide a '' | ||
+ | |||
+ | ==== Javascript + Frontend-tests ==== | ||
+ | |||
+ | |||
+ | FIXME This section needs to be rewritten for Github Actions since Travis is no longer recommended. | ||
+ | |||
+ | It is possible to integrate javascript-tests written in [[http:// | ||
+ | |||
+ | <file foo .travis.yml> | ||
+ | language: php | ||
+ | php: | ||
+ | - " | ||
+ | - " | ||
+ | - " | ||
+ | env: | ||
+ | - DOKUWIKI=master | ||
+ | - DOKUWIKI=stable | ||
+ | - DOKUWIKI=old-stable | ||
+ | before_install: | ||
+ | - wget https:// | ||
+ | - npm install | ||
+ | install: sh travis.sh | ||
+ | script: | ||
+ | - cd _test && phpunit --stderr --group plugin_yourplugin | ||
+ | - cd ../ | ||
+ | </ | ||
+ | |||
+ | npm needs a '' | ||
+ | |||
+ | <file json package.json> | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | grunt needs a '' | ||
+ | |||
+ | <file javascript Gruntfile.js> | ||
+ | module.exports = function(grunt) { | ||
+ | grunt.initConfig({ | ||
+ | pkg: grunt.file.readJSON(' | ||
+ | |||
+ | qunit: { | ||
+ | all: [' | ||
+ | } | ||
+ | }); | ||
+ | grunt.loadNpmTasks(' | ||
+ | grunt.registerTask(' | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | Finally the qunit html-files have to be adjusted to be able to work with node_modules for automated testing and with online-libraries for browser-testing: | ||
+ | |||
+ | <file html qunit.test.html> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <meta charset=" | ||
+ | < | ||
+ | <link rel=" | ||
+ | <script src=" | ||
+ | < | ||
+ | </ | ||
+ | < | ||
+ | <div id=" | ||
+ | <div id=" | ||
+ | <script src=" | ||
+ | < | ||
+ | <script src=" | ||
+ | <script src=" | ||
+ | |||
+ | |||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | See the [[https:// | ||
+ | |||
=====See also==== | =====See also==== | ||
+ | * [[devel: | ||
* [[devel: | * [[devel: |
devel/unittesting.1401930278.txt.gz · Last modified: 2014-06-05 03:04 by samwilson