You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When execution time of your tests is longer than a coffee break, it is a good reason to think about making your tests faster. If you have already tried to run them on SSD drive, and the execution time still upsets you, it might be a good idea to run your tests in parallel. However, PHP runs in a single-process and you can't parallelize tests natively similarly to how this works in Java or in NodeJS. In this guide we will overview the options you have to run your tests in parallel.
3
+
When execution time of your tests is longer than a coffee break, it is a good reason to think about making your tests faster. If you have already tried to run them on SSD drive, and the execution time still upsets you, it might be a good idea to run your tests in parallel. However, PHP runs in a single-process and you can't parallelize tests natively similarly to how this works in Java or in NodeJS.
4
4
5
-
Parallel Test Execution consists of 3 steps:
6
-
7
-
* splitting tests
8
-
* running tests in parallel
9
-
* merging results
10
-
11
-
Depending on the project size and requirements you can choose the proper way to implement parallel testing.
5
+
Depending on the project size and requirements you can choose how the best to implement parallel testing for your case.
12
6
In this guide we will overview possible options.
13
7
14
-
## Continuous Integration
15
-
16
-
If you use modern Continuous Integration setup you can split your tests by jobs and run them in parallel.
17
-
In this case the burden of parallelization lies on CI server.
18
-
This makes a lot of sense as a single machine has limited resources. So even if PHP could spawn multiple processes with tests at one point you would still need to split tests in CI jobs.
19
-
If you split tests into CI jobs, you are limited only to the number of agents (build servers) that the CI can provide. For cloud-based services like GitHub Actions, GitLab CI, CircleCI, etc, this number is unlimited.
20
-
21
-

22
-
23
-
On the first stage, tests should be split into groups. The group file should be committed into the repository or passed to next stage as an artifact.
24
-
25
-
On the second stage tests are executed. XML, HTML, and CodeCoverage reports must be stored as artifacts.
26
-
27
-
On the third stage the results from previous jobs must be collected or aggregated.
28
-
29
8
## Sharding
30
9
31
10
Minimal setup can be implemented by executing several independent CI jobs and running.
@@ -63,7 +42,17 @@ By running tests with Testomat.io reporter attached results will be sent to a ce
63
42
TESTOMATIO={apiKey} TESTOMATIO_TITLE="Build $BUILDID" ./vendor/bin/codecept run --shard 3/4
64
43
```
65
44
66
-
## Building Pipeline
45
+
46
+
## Building Pipeline
47
+
48
+
While sharding provides a simplified setup for testing the complete pipeline schema may look like this.
49
+
50
+

51
+
52
+
* On the first stage, tests should be split into groups. The group file should be committed into the repository or passed to next stage as an artifact.
53
+
* On the second stage tests are executed. XML, HTML, and CodeCoverage reports must be stored as artifacts.
54
+
* On the third stage the results from previous jobs must be collected or aggregated.
55
+
67
56
68
57
To get more control on how the jobs are split excuted and results aggregated you can use a task runner.
@@ -143,34 +123,13 @@ class Robofile extends \Robo\Tasks
143
123
144
124
{% endhighlight %}
145
125
146
-
If you run `robo`, you can see the respective commands:
126
+
When running `robo` you should see all 3 that these methods availble as CLI commands:
147
127
148
-
{% highlight bash %}
149
-
150
-
$ robo
151
-
Robo version 0.6.0
152
-
153
-
Usage:
154
-
command [options] [arguments]
155
-
156
-
Options:
157
-
-h, --help Display this help message
158
-
-q, --quiet Do not output any message
159
-
-V, --version Display this application version
160
-
--ansi Force ANSI output
161
-
--no-ansi Disable ANSI output
162
-
-n, --no-interaction Do not ask any interactive question
163
-
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
164
-
165
-
Available commands:
166
-
help Displays help for a command
167
-
list Lists commands
168
-
parallel
169
-
parallel:merge-results
170
-
parallel:run
171
-
parallel:split-tests
172
-
173
-
{% endhighlight %}
128
+
```
129
+
parallel:split-tests
130
+
parallel:run
131
+
parallel:merge-results
132
+
```
174
133
175
134
#### Step 1: Split Tests
176
135
@@ -211,10 +170,13 @@ Tasks from `\Codeception\Task\SplitTestsByGroups` will generate non-intersecting
211
170
212
171
{% endhighlight %}
213
172
173
+
But what if one group of your tests runs for 5 mins and other for 20mins. In this case, you can balance execution time by using [SplitTestsByTime](https://github.com/Codeception/robo-paracept#splittestsbytime) task. It will generate balanced groups taking the execution speed into account.
174
+
175
+
> More splitting strategies are implemented within [Robo-paracept](https://github.com/Codeception/robo-paracept#tasks) package.
@@ -239,38 +201,20 @@ Let's try to execute tests from the second group:
239
201
240
202
{% highlight bash %}
241
203
242
-
$ codecept run acceptance -g paracept_2
204
+
$ php vendor/bin/codecept run acceptance -g paracept_2
243
205
244
206
{% endhighlight %}
245
207
246
208
#### Step 2: Running Tests
247
209
248
-
Robo has `ParallelExec` task to spawn background processes.
249
-
250
-
##### Inside Container
210
+
At this point you should decide if tests are executed on the same job or use multiple jobs for them. We recommend using multiple jobs, as in this case the burden of parallelization goes to CI server. This makes a lot of sense as a single machine has limited resources. If you split tests into CI jobs, you are limited only to the number of agents (build servers) that the CI can provide. For cloud-based services like GitHub Actions, GitLab CI, CircleCI, etc, this number is unlimited.
251
211
252
-
If you are using [Docker](#docker) containers you can launch multiple Codeception containers for different groups:
253
-
254
-
{% highlight php %}
212
+
> Please refer to documentation of your CI platform to learn how to set up multiple jobs runnninng in parallel. Then proceed to merging of results.
255
213
256
-
public function parallelRun()
257
-
{
258
-
$parallel = $this->taskParallelExec();
259
-
for ($i = 1; $i <= 5; $i++) {
260
-
$parallel->process(
261
-
$this->taskExec('docker-compose run --rm codecept run')
262
-
->option('group', "paracept_$i") // run for groups paracept_*
263
-
->option('xml', "tests/_log/result_$i.xml") // provide xml report
264
-
);
265
-
}
266
-
return $parallel->run();
267
-
}
268
-
269
-
{% endhighlight %}
214
+
In some situations you may want to keep tests running on the same machine and scale it up with more resourses. This makes sense if you have heavy application setup for each test run and setting it up for each machine can waste a lot of resources.
270
215
271
-
##### Locally
272
216
273
-
If you want to run tests locally just use preinstalled `taskCodecept` task of Robo to define Codeception commands and put them inside `parallelExec`.
217
+
To execute tests in multiple processes Robo has `ParallelExec` task to spawn background processes.
274
218
275
219
{% highlight php %}
276
220
@@ -304,41 +248,37 @@ $ robo parallel:run
304
248
In case of `parallelExec` task we recommend to save results as JUnit XML, which can be merged and plugged into Continuous Integration server.
`result_paracept.xml` file will be generated. It can be processed and analyzed.
327
267
328
-
#### All Together
268
+
`result_paracept.xml` file will be generated. It can be processed and analyzed.
329
269
330
-
To create one command to rule them all we can define new public method `parallelAll` and execute all commands. We will save the result of `parallelRun` and use it for our final exit code:
270
+
If you prefer HTML reports, they can be generated in the same way:
0 commit comments