devel:unittesting
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
devel:unittesting [2024-04-05 17:12] – 90.186.128.233 | devel:unittesting [2024-04-06 11:40] (current) – old revision restored (2024-03-09 23:41) saggi | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== | + | ====== |
+ | |||
+ | Very briefly explained, [[wp> | ||
+ | |||
+ | DokuWiki' | ||
+ | |||
+ | We use the [[http:// | ||
+ | |||
+ | ===== Setup ===== | ||
+ | |||
+ | Install the needed requirements using [[composer]]: | ||
- | * installiere bluetooth Tool falls nicht vorhanden: | ||
< | < | ||
- | apt install | + | cd dokuwiki/ |
+ | composer | ||
</ | </ | ||
- | * öffne Bluetooth Interface | + | |
+ | ===== Running Tests ===== | ||
+ | |||
+ | Running the test suite is simple, here's how. | ||
+ | |||
+ | ==== All Tests ==== | ||
+ | |||
+ | Just change to the '' | ||
< | < | ||
- | bluetoothctl | + | cd _test/ |
+ | composer run test | ||
</ | </ | ||
- | ^ Befehl | ||
- | | agent on/ | ||
- | | scan on/ | ||
- | | pair < | ||
- | | connect < | ||
- | | trust < | ||
+ | ==== Single Test Files ==== | ||
+ | |||
+ | You can run a specific test file by giving it as a parameter: | ||
+ | |||
+ | cd _test | ||
+ | composer run test tests/ | ||
+ | |||
+ | ==== Grouped Tests ==== | ||
+ | |||
+ | You include or exclude tests by their group: | ||
+ | |||
+ | <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 | ||
+ | </ | ||
+ | |||
+ | Note the ''< | ||
+ | |||
+ | ==== 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 ===== | ||
+ | |||
+ | 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:// | ||
+ | |||
+ | ==== Naming Conventions ==== | ||
+ | |||
+ | Every new bit of code should follow [[https:// | ||
+ | |||
+ | In accordance ẃith PHPUnit conventions test classes should end in '' | ||
+ | |||
+ | This means a class '' | ||
+ | |||
+ | Each test class need to inherit from [[xref> | ||
+ | |||
+ | |||
+ | For legacy, functional code no namespace is used. Tests are located in the sub directories '' | ||
+ | |||
+ | |||
+ | ==== Environment ==== | ||
+ | |||
+ | Our testsuite runs a '' | ||
+ | |||
+ | * setup a minimal '' | ||
+ | * create a custom config directory in the system' | ||
+ | * with default configs | ||
+ | * some overrides from '' | ||
+ | * rerun DokuWiki initialization | ||
+ | |||
+ | This setup won't load any plug-ins. If you need to enable a plug-in you can override the '' | ||
+ | |||
+ | ^ //Note:// Remember to call '' | ||
+ | |||
+ | Additionally the test suite runs a '' | ||
+ | * reload the DokuWiki config | ||
+ | * reload the plugin controller and plug-ins | ||
+ | * reload the event handler | ||
+ | * ensure the existence of some files (see [[xref> | ||
+ | * ensure DokuWiki paths (see [[xref> | ||
+ | * reload global variables like '' | ||
+ | |||
+ | ^ //Note:// Remember to call '' | ||
+ | |||
+ | 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 ==== | ||
+ | |||
+ | Unit tests should test minimal code parts (units) whenever possible. But with a complex application like DokuWiki this isn't always possible. This is why our test suite allows to run simple integration tests as well using a fake request. | ||
+ | |||
+ | Using this mechanism a HTTP request is faked and the resulting HTML output can be inspected. This also allows for testing plugin events. | ||
+ | |||
+ | === Running a request === | ||
+ | |||
+ | The [[xref> | ||
+ | |||
+ | - Initialization | ||
+ | - Prepare request | ||
+ | - send request | ||
+ | |||
+ | The initialization is done by: | ||
+ | <code php> | ||
+ | $request = new TestRequest(); | ||
+ | </ | ||
+ | |||
+ | Once it's initialized you can prepare the request. | ||
+ | The preparation can be register event hooks or setting request variables. | ||
+ | |||
+ | The request variables are set via setter methods and look like: | ||
+ | |||
+ | ^ Variable | ||
+ | | '' | ||
+ | | '' | ||
+ | | '' | ||
+ | | '' | ||
+ | |||
+ | |||
+ | Finally you have to execute the request. This can be done by calling the '' | ||
+ | <code php> | ||
+ | $response = $request-> | ||
+ | </ | ||
+ | |||
+ | Additionally there are two methods for '' | ||
+ | |||
+ | <code php> | ||
+ | // a get request | ||
+ | $response = $request-> | ||
+ | // a post request | ||
+ | $response = $request-> | ||
+ | </ | ||
+ | |||
+ | The result of a request is a [[xref> | ||
+ | |||
+ | === Example: Event hooks === | ||
+ | |||
+ | 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 an event followed by an '' | ||
+ | |||
+ | <code php> | ||
+ | public function testHookTriggering() | ||
+ | { | ||
+ | global $EVENT_HANDLER; | ||
+ | |||
+ | $request = new TestRequest(); | ||
+ | $hookTriggered = false; // initialize a test variable | ||
+ | |||
+ | // register a hook | ||
+ | $EVENT_HANDLER-> | ||
+ | function() use (& | ||
+ | $hookTriggered = true; | ||
+ | } | ||
+ | ); | ||
+ | |||
+ | // do the request | ||
+ | $request-> | ||
+ | | ||
+ | // check the result of our variable | ||
+ | $this-> | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | === Example: Using php-dom-wrapper after a request === | ||
+ | |||
+ | Sometimes you want to inspect the resulting html of a request. | ||
+ | To provide a little comfort we use the [[https:// | ||
+ | |||
+ | With this you can operate in a jQuery like style on the returned HTML. | ||
+ | |||
+ | Two simple examples are: | ||
+ | <code php> | ||
+ | public function testSimpleRun() | ||
+ | { | ||
+ | // make a request | ||
+ | $request = new TestRequest(); | ||
+ | $response = $request-> | ||
+ | |||
+ | // get the generator name from the meta tag. | ||
+ | $generator = $response-> | ||
+ | -> | ||
+ | |||
+ | // check the result | ||
+ | $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 ==== | ||
+ | |||
+ | 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 ''< | ||
+ | |||
+ | 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 '' | ||
+ | |||
+ | Plugin tests should declare a group for all their tests named '' | ||
+ | |||
+ | If your plugin needs additional files during testing, you can copy them to the test directory in a '' | ||
+ | |||
+ | Here's a small example: | ||
+ | |||
+ | <code php> | ||
+ | /** | ||
+ | * @group plugin_data | ||
+ | * @group plugins | ||
+ | */ | ||
+ | class helper_plugin_data_test extends DokuWikiTest | ||
+ | { | ||
+ | |||
+ | protected $pluginsEnabled = [' | ||
+ | |||
+ | public static function setUpBeforeClass(){ | ||
+ | parent:: | ||
+ | // copy our own config files to the test directory | ||
+ | TestUtils:: | ||
+ | } | ||
+ | |||
+ | public function testExample() { | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | A plugin' | ||
+ | |||
+ | <code php> | ||
+ | public function setUp() | ||
+ | { | ||
+ | global $conf; | ||
+ | |||
+ | parent:: | ||
+ | |||
+ | $conf[' | ||
+ | $conf[' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | So the correct indexing for plugins is '' | ||
+ | |||
+ | ===== Continous Integration with Github Actions ===== | ||
+ | |||
+ | |||
+ | Plugin authors are encouraged to have their tests run automatically on Github Actions.The [[http:// | ||
+ | |||
+ | ==== 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==== | ||
+ | * [[devel: | ||
+ | * [[devel: |
devel/unittesting.txt · Last modified: 2024-04-06 11:40 by saggi