Skip to content

Commit 411fdc9

Browse files
authored
Merge pull request #1234 from andrewnicols/phpunit11
[docs] Add PHPUnit 11 upgrade guidance
2 parents 5f2ced2 + a5ce0db commit 411fdc9

File tree

8 files changed

+210
-5
lines changed

8 files changed

+210
-5
lines changed

data/migratedPages.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1576,7 +1576,7 @@ Overview:
15761576
- filePath: "/general/community/intro.md"
15771577
slug: "/general/community"
15781578
PHPUnit:
1579-
- filePath: "/general/development/tools/phpunit.md"
1579+
- filePath: "/general/development/tools/phpunit/index.md"
15801580
slug: "/general/development/tools/phpunit"
15811581
Peer_reviewing:
15821582
- filePath: "/general/development/process/peer-review.md"

docs/devupdate.md

+8
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,11 @@ $activity-icon-interactivecontent-bg: #c70827;
8585
```
8686

8787
:::
88+
89+
## Unit Tests
90+
91+
<Since version="5.0" issueNumber="MDL-83468" />
92+
93+
Moodle has updated the version of PHPUnit used in core to version 11.4. Some tests may encounter issues as a result.
94+
95+
Please see the [PHPUnit 11 Upgrade Guide](/general/development/tools/phpunit/upgrading-11) for assistance in updating any broken tests.

general/development/policies.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ Moodle uses a framework called [PHPUnit](https://github.com/sebastianbergmann/ph
182182

183183
:::info
184184

185-
For more about this, see [PHPUnit](./tools/phpunit.md).
185+
For more about this, see [PHPUnit](./tools/phpunit/index.md).
186186

187187
:::
188188

general/development/policies/codingstyle/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1768,7 +1768,7 @@ There are some tags that are only allowed within some contexts and not globally.
17681768
- `@covers`, `@coversDefaultClass`, `@coversNothing`, `@uses` to better control coverage within [unit tests](https://docs.moodle.org/dev/Writing_PHPUnit_tests#Generators).
17691769
- `@dataProvider` and `@testWith`, to provide example data and expectations, within [unit tests](https://docs.moodle.org/dev/Writing_PHPUnit_tests#Generators).
17701770
- `@depends`, to express dependencies between tests, where each producer returned data in passed to consumers. See [`@depends` examples](https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#writing-tests-for-phpunit-examples-stacktest2-php) for more information.
1771-
- `@group`, for easier collecting unit tests together, following the guidelines in the [PHPUnit MoodleDocs](../../tools/phpunit.md#using-the-group-annotation).
1771+
- `@group`, for easier collecting unit tests together, following the guidelines in the [PHPUnit MoodleDocs](../../tools/phpunit/index.md#using-the-group-annotation).
17721772
- `@requires`, to specify unit test requirements and skip if not fulfilled. See [`@requires` usages](https://docs.phpunit.de/en/9.6/incomplete-and-skipped-tests.html#incomplete-and-skipped-tests-requires-tables-api) for more information.
17731773
- `@runTestsInSeparateProcesses` and `@runInSeparateProcess`, to execute an individual test or a testcase in isolation. To be used only when strictly needed.
17741774

general/development/process.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ The process of [new feature development](#new-feature-development) is described
135135

136136
### Testing
137137

138-
During development, as new code is integrated, automated testing conducted at the [code](./tools/phpunit.md) and [interface](./tools/behat/index.md) levels, to make sure there are no regressions caused by new features.
138+
During development, as new code is integrated, automated testing conducted at the [code](./tools/phpunit/index.md) and [interface](./tools/behat/index.md) levels, to make sure there are no regressions caused by new features.
139139

140140
In the last month before the release, a feature freeze is called (no new features can be added) and volunteer testers from the Moodle community perform manual [QA testing](./process/testing/qa.md) of Moodle features. The current set of functional tests is listed in [MDLQA-1](https://tracker.moodle.org/browse/MDLQA-1). The list of tests is extended as new features are added, though we're also trying to reduce the number as more automated [acceptance tests](./tools/behat/index.md) are developed.
141141

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
---
2+
title: PHPUnit 11 Upgrade
3+
tags:
4+
- Testing
5+
- PHPUnit
6+
---
7+
8+
<Since version="5.0" issueNumber="MDL-83468" />
9+
10+
Moodle 5.0 updated the version of PHPUnit from version 9.6 to version 11.
11+
12+
This guide is intended to help you update your tests to work with the newer versions.
13+
14+
## Why did we make this change?
15+
16+
PHPUnit 9.6 is currently in maintenance support, but we don't know for how much longer.
17+
18+
We ultimately _need_ to update to a newer version of PHPUnit at some point to ensure that PHP version incompatibilities are addressed and we are able to keep testing Moodle properly.
19+
20+
The most appropriate target is for Moodle 5.0 which follows our new Series naming and versioning policies.
21+
22+
### Why not PHPUnit 10?
23+
24+
- PHPUnit 10 is the next major version of PHPUnit and introduces a number of compatibility issues with PHPUnit 9.6.
25+
- PHPUnit 11 is the latest major version of PHPUnit and is _more_ backwards compatible with PHPunit 9.6 than PHPUnit 10 is.
26+
27+
Many of the features removed in PHPUnit 10 were then partially added back in PHPUnit 11.
28+
29+
To give a specific example, PHPUnit 9.6 has a `--debug` flag. This was removed in 10.0, and added back in 11.0 as an alias for a combination of other flags.
30+
31+
There are lots of other examples of this kind of thing.
32+
33+
## Can I make my tests work in both 9.6 and 11.4?
34+
35+
Yes, _usually_. But it may require some changes to your tests and/or code. For the most part any such changes are usually a good thing and are usually because the tests were wrong in the first place.
36+
37+
### I still can't make my tests work in both 9.6 and 11.4
38+
39+
Unfortunately there is only so much we can do about this -- we can't support every possible combination of PHPUnit versions and we are limited by the versions of PHPUnit that are available in the PHP ecosystem for the versions of PHP that we support.
40+
41+
One of the changes to Moodle's versioning policy was intended to make a balance between core maintainability, and plugin maintainability. Whilst we always strive to avoid making a breaking change to plugins, and to provide a stable for all _currently_ supported versions of Moodle, sometimes this is not possible.
42+
43+
We do recommend that you create a new branch of your plugin for _each series release of Moodle_. That is recommend you have a branch for Moodle 4.x, and separate branch for Moodle 5.x.
44+
45+
## Help -- my tests are broken!
46+
47+
Generally speaking we have already tried to minimise the impact of this change by updating to PHPUnit 9.6 on all stables, which already had some support for some of the new 11.4 features.
48+
49+
We've documented all of the issues we encountered in this transition below.
50+
51+
### Empty data providers
52+
53+
#### Problem
54+
55+
Data providers _must_ now provide data. You cannot have data providers which return an empty Iterator/Array.
56+
57+
#### Solution - use the `@requires` annotation
58+
59+
You may be able to use the [`@requires`](https://docs.phpunit.de/en/9.6/annotations.html#requires) annotation to skip your test based on some configuration, for example whether a specific PHP Extension is installed, for example:
60+
61+
```php
62+
/**
63+
* @requires extension Redis
64+
*/
65+
```
66+
67+
#### Solution - skip the provider within the test
68+
69+
You may need to perform some check within your test, and/or add a param to the data provider to say whether it should be skipped.
70+
71+
### Tests now failing with `assertEqualsCanonicalizing`
72+
73+
#### Problem
74+
75+
PHPUnit 10 made some changes to `assertEqualsCanonicalizing` which mean that it now compares the array _keys_ as well as the array _values_.
76+
77+
This may be observed in some situations but not others, or inconsistently. This is especially true if the values are coming from the database without a `SORT BY` clause.
78+
79+
#### Solution - Ensure your data is consistently sorted
80+
81+
In some cases you may need to ensure that the data returned from the database is consistently sorted.
82+
83+
:::note
84+
85+
You should only do this if you want the data presented to the user to be sorted consistently.
86+
87+
If it does not matter what order the data is _fetched_, then see the next solution instead.
88+
89+
:::
90+
91+
#### Solution - Remove the array keys
92+
93+
You may need to wrap your asserted value in `array_values()` if the keys are not important.
94+
95+
### The `setMethods` method on the `MockBuilder` is deprecated and removed
96+
97+
#### Problem
98+
99+
The `setMethods` method was deprecated in PHPUnit 8.3.0 and removed in PHPUnit 10.
100+
101+
See [PHPUnit Issue #3687](https://github.com/sebastianbergmann/phpunit/issues/3687) for further information on the rationale.
102+
103+
#### Solutions
104+
105+
You can:
106+
107+
- remove the call entirely;
108+
- replace with `onlyMethods`
109+
- replace with `addMethods`
110+
- refactor your test as appropriate
111+
112+
### Some methods have been deprecated and/or removed
113+
114+
#### Problem
115+
116+
Some methods have been deprecated and/or removed. In some cases Moodle has polyfilled these:
117+
118+
- `assertTag`
119+
- `getName`
120+
- `isInIsolation`
121+
122+
#### Solutions
123+
124+
You can:
125+
126+
- remove the call entirely;
127+
- polyfill it within your own TestCase class.
128+
129+
### Data providers must be static
130+
131+
#### Problem
132+
133+
PHPUnit has always supported _static_ data providers, but also supported non-static ones.
134+
135+
That is, the following was accepted:
136+
137+
```php
138+
protected function my_data_provider(): array {
139+
return [...];
140+
}
141+
```
142+
143+
PHPUnit has required that data providers be both public, and static, since version 10.
144+
145+
We've known this change has been coming for some time and have been working to remove all non-static data providers from core.
146+
147+
Non-static data providers was then removed in PHPunit 11.
148+
149+
#### Solutions
150+
151+
You must make the data provider static. Where this is non-trivial it probably highlights an existing bug in your tests.
152+
153+
Things we found:
154+
155+
- objects created in the data provider
156+
- DB calls made in the provider
157+
- other side effects
158+
159+
The [moodle-cs](../phpcs.md) coding style rules for phpcs can help you to fix this issue.
160+
161+
### Data providers returning keyed arrays must match the parameter names in their test
162+
163+
#### Problem
164+
165+
If you have a data provider such as the following:
166+
167+
```php
168+
public static function my_provider(): array {
169+
return [
170+
[
171+
'foo' => 'bar',
172+
'baz' => 'qux',
173+
],
174+
]''
175+
}
176+
```
177+
178+
Then the test that uses this data provider must have the same parameter names:
179+
180+
```php
181+
/**
182+
* @dataProvider my_provider
183+
*/
184+
public function test_my_test(string $foo, string $baz) {
185+
...
186+
}
187+
```
188+
189+
If the parameter names do not match, PHPUnit will throw a warning.
190+
191+
There is also a warning if the data provider returns a mix of named and unnamed keys.
192+
193+
#### Solutions
194+
195+
- Change the parameter names in the test to match the data provider
196+
- Change the data provider to match the parameter names in the test
197+
- Remove the names

general/releases/2.3.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ Few changes could break existing web service clients in 2.3 - untill this versio
252252

253253
#### Unit tests
254254

255-
We have switched completely to using [PHPUnit](../development/tools/phpunit.md) for all our unit tests now. All existing simpletests have been rewritten, and new tests have been added.
255+
We have switched completely to using [PHPUnit](../development/tools/phpunit/index.md) for all our unit tests now. All existing simpletests have been rewritten, and new tests have been added.
256256

257257
We intend to move towards a completely unit-test-driven development methodology (where the tests are written first!) for significant new code, and we also encourage all developers to implement unit tests covering at least the core features of their code.
258258

0 commit comments

Comments
 (0)