Show last authors
1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
4
5 = Usage =
6
7 * Based on [[TestContainers>>https://www.testcontainers.org/]] and uses Docker to execute the tests under various Databases, Servlet Engines and Browsers.
8 ** [[Introductory talk about TestContainers and XWiki at Devoxx FR 2019>>https://youtu.be/0TvWv4L_IJM]] (In French)
9 * The only requirements for running these tests is to have Docker installed locally and to have the user under which you run your IDE and the Maven build be able to use the docker executable.
10 * Tests are marked as docker-based tests with the ##@UITest## annotation.
11 * Tests get injected ##XWikiWebDriver##, ##TestUtils##, ##TestInfo##, ##TestReference## and ##TestLocalReference## instances as test method parameters.
12 * Test results is recording in a FLV file in the ##target## directory.
13 * A screenshot of the UI when the test is failing is also taken in the ##target## directory.
14 * When test execute it's possible to connect to the running VNC server and see the UI by using a VNC client and connect to the VNC URL printed in the console, e.g. ##vnc:~/~/vnc:[email protected]:32936##.
15 ** Note that if you want to debug and interact with the XWiki UI you should use a ##servletEngine## other than the default Jetty Standalone one since otherwise the debug point in your IDE will prevent the XWiki code from executing and you'll see a spinning wheel until you step forward in your debugger. You can use for example ##servletEngine = ServletEngine.TOMCAT##.
16 * The version for the platform dependencies is specified using the ##platform.version## property in the ##pom.xml## file executing the tests.
17 * The test configuration options can be accessed from tests by specifying a method parameter of type ##TestConfiguration## (see examples below).
18 ** You can get access to the IP address/port to use to connect to XWiki from the host machine: ##testConfiguration.getServletEngine().getIP()/getPort()##
19 ** You can get access to the IP address to use to connect to the host machine from inside XWiki: ##testConfiguration.getServletEngine().getHostIP()##
20 ** You can get access to the IP address/port used internally by XWiki (for example to generate URLs): ##testConfiguration.getServletEngine().getInternalIP()/getInternalPort()##
21 * A special source for ##@ParameterizedTest## is available to inject subwikis as input for a test
22
23 = Configurations options =
24
25 {{info}}
26 Note:
27
28 * When passing as Java annotation attributes, in functional tests, the format is ##@UITest(<Option Name> = <Value>)##
29 * When passing the options as System Properties, the format is ##-Dxwiki.test.ui.<Option Name>=<Value>##
30 ** Except for passing ##properties## where the format is ##-Dxwiki.test.ui.properties.<Property name>=<Property Value>##
31 ** Except for ##extraJARs##, ##sshPorts## & ##forbiddenServletEngines## which cannot be set from System Properties.
32 ** Except for passing ##databaseCommands## where the format is ##-Dxwiki.test.ui.database.commands.<Command name>=<Command Value>##
33 * System properties have priority over Java annotation attributes
34 * The ##xwiki.test.ui.dependencies## configuration value can only be passed as a system property.
35 {{/info}}
36
37 (% style="overflow-x: auto;" %)
38 (((
39 |=Option Name|=Default Value|=Valid Values|=Description
40 |##browser##|##firefox##|(((
41 * ##firefox## (##Browser.FIREFOX##)
42 * ##chrome## (##Browser.CHROME##)
43 )))|The browser used in the tests. Note that the version of the browser used is controlled by the version of Selenium that is defined in the ##pom.xml## of ##xwiki-platform-test-docker##.
44 |##database##|##hsqldb_embedded##|(((
45 * ##mysql## (##Database.MYSQL##)
46 * ##postgresql## (##Database.POSTGRESQL##)
47 * ##hsqldb_embedded## (##Database.HSQLDB_EMBEDDED##)
48 * ##oracle DB## (##Database.ORACLE##)
49 )))|The database used in the tests. Available tags are those listed on the Dockerhub page for the database image used. Note: for Oracle, we have a [[custom image>>https://hub.docker.com/r/xwiki/oracle-database/tags?page=1&ordering=last_updated]].
50 |##servletEngine##|##jetty_standalone##|(((
51 * ##tomcat## (##ServletEngine.TOMCAT##)
52 * ##jetty## (##ServletEngine.JETTY##)
53 * ##jetty_standalone## (##ServletEngine.JETTY_STANDALONE##)
54 * ##external## (##ServletEngine.EXTERNAL##)
55 )))|The Servlet Engine used in the tests. Use ##external## to use your own started and alreayd provisioned XWiki instance.
56 |##verbose##|##false##|(((
57 * ##true##
58 * ##false##
59 )))|When active, displays more logs in the console (especially container startup logs)
60 |##debug##|##false##|(((
61 * ##true##
62 * ##false##
63 )))|When active, starts XWiki in debug mode when using the "Jetty Standalone" and Tomcat Servlet Engines (and starts it with suspend on, i.e. wait for the remote debugger to connect to it before progressing, to make it easy to debug XWiki's server side). You can then attach a remote debugger. Since Tomcat runs in a Docker container, you'll need to do a ##docker ps## to find the local mapped port corresponding to port 5005 and then use ##localhost## as the JVM host name.
64 |##office##|##false##|(((
65 * ##true##
66 * ##false##
67 )))|(((
68 When active it creates or gets a custom docker image based on the servlet engine image provided but with LibreOffice installed on it. The created image is named and tagged using the following scheme: ##xwiki-[servlet engine name]-office:[servlet engine tag]##.
69
70 The LibreOffice version used for the install is based on the Maven property ##libreoffice.version##.
71 )))
72 |##offline##|##false##|(((
73 * ##true##
74 * ##false##
75 )))|When offline, the custom XWiki WAR generation and the XWiki provisioning are done solely from your local Maven repository. Otherwise, when artifacts are not present locally or newer SNAPSHOT versions are available, they'll be fetched from Maven remote repositories. Moreover no docker pull check is performed in offline mode.
76 |##databaseTag##|##latest##|Any Docker tag available from Dockerhub for the container image|Version of the database to use. Isn't supported for HSQLDB Embedded since it doesn't run in a Docker container. See the [[latest supported version by XWiki>>Community.DatabaseSupportStrategy]].
77 |##servletEngineTag##|Default tag version defined by TestContainers|Any Docker tag available from Dockerhub for the container image|Version of the Servlet Engine to use. Isn't supported for Jetty Standalone since it doesn't run in a Docker container. See the [[latest supported version by XWiki>>Community.ServletContainerSupportStrategy.WebHome]].
78 |##jdbcDriverVersion##|Latest version validated by the XWiki dev team|Any version for the specified database that is available on Maven Central, e.g. for MySQL the groupId/artifactId is ##mysql##/##mysql-connector-java##.|
79 |##vnc##|##true##|(((
80 * ##true##
81 * ##false##
82 )))|When active a VNC container is started to record a video of the tests and more generally to allow connecting to the UI running the tests. Useful when debugging.
83 |##properties##|No default (empty)|Check the ##*.vm## files for the configuration files to see the list of possible values.|(% style="word-break:break-all" %)Velocity properties that are applied when generating XWiki's configuration files: ##xwiki.cfg##, ##xwiki.properties## and ##hibernate.cfg.xml##. Example: Tell XWiki that minification is off: ##-Dxwiki.test.ui.properties.xwikiPropertiesAdditionalProperties=debug.minify=false## or ##@UITest(properties = { "xwikiPropertiesAdditionalProperties=debug.minify=false" })##. Note that the ##xwikiCfgPlugins## property will be merged with the default values unless you start the new property value with the ##^## character.
84 |##extraJARs##|No default (empty)|Comma-separated list of ##<groupId>:<artifactId>## or ##<groupId>:<artifactId>:<version>##|(% style="word-break:break-all" %)There are cases where the module being tested cannot be fully deployed as an extension into a running XWiki and it needs to deploy one or several JARs into ##WEB-INF/lib## (as core extensions). One such example is when an extension includes a Hibernate HBM file, as right now only HBM files located in JARs in ##WEB-INF/lib## are supported. Note that when the version is not specified the current POM's version is used.
85 |##sshPorts##|No default (empty)|List of integers|The list of ports that should be SSH-forwarded when connecting from a Docker container to the host (i.e. when using the ##host.testcontainers.internal##. This is in addition to port ##8080## which is always added. For example if you need XWiki to send a mail to a SMTP server running on port 3025 on the host, you should add port 3025 to the list.
86 |##profiles##|No default (empty)|Comma-separated list of Maven profile ids|When specified the defined profiles are active when resolving dependencies from the current POM.
87 |##forbiddenServletEngines##|No default (empty)|List of ##ServletEngine##s enums|List of Servlet Engines for which the tests will be skipped (usually because they'd fail on them).
88 |##databaseProperties##|No default (empty)|See Docker documentation for the target image|List of database docker commands to use and that will override default commands (example of command ##character-set-server=utf8mb4## which will translate into ##~-~-character-set-server=utf8mb4## at runtime).
89 |##dependencies##|No default (empty)|Comma-separated list of Maven coordinates|List artifacts that will be provisioned in the running XWiki instance. When specified then current pom.xml dependencies are not used to find out what to provision. This can be used for example in cases when you don't want to use project dependencies in order to not draw older version of dependencies (such as when you need to run functional docker-based tests in a specific more recent vesion of XWiki than the one used to build the code). Accepted format is ##groupId:artifactId##, ##groupId:artifactId:version## and ##groupId:artifactId:type:version##. {{info}}Since 11.2RC1{{/info}}.
90 |##extensionOverrides##|No default (empty)|List Extension Manager overrides|See example below for the format. {{info}}Since 11.6RC1{{/info}}.
91 |##resolveExtraJARs##|##false##|(((
92 * ##true##
93 * ##false##
94 )))|Specifies if the extra JAR versions must be resolved (when their versions are not specified), by checking the transitive list of dependencies in the current POM. Note that there are 2 limitations: resolving takes time and SNAPSHOT versions will be resolved to the latest published SNAPSHOT. This is why it's off by default. When false the current POM version will be used for the missing exyta JAR versions. The main use case for using true is in contrib extensions where the current POM version usually don't match extra JARs versions and you may not want to hardcode the version and thus you can let the docker test framework find it for you. {{info}}Since 12.5RC1{{/info}}.
95 |##saveDatabaseData##|##false##|(((
96 * ##true##
97 * ##false##
98 )))|By default, database data is not saved between test executions. {{warning}}Note that if you decide to save database data, they'll be saved under a ##docker## user by Docker and you need your local user to be able to remove them if you want to clean your Maven ##target## directory.{{/warning}}
99 |##savePermanentDirectoryData##|##false##|(((
100 * ##true##
101 * ##false##
102 )))|Allows to persist the XWiki permanent directory in the Maven target directory, after the test has finished executing. This can be useful for debugging purposes, especially when executing remotely without an IDE (on a CI agent for example). {{info}}Since 14.5{{/info}}.
103
104 = Examples =
105
106 == Full Examples ==
107
108 * {{scm path="xwiki-platform-core/xwiki-platform-menu/xwiki-platform-menu-test/xwiki-platform-menu-test-docker/src/test/it/org/xwiki/menu/test/ui/MenuIT.java"}}MenuIT{{/scm}}
109 * {{scm path="xwiki-platform-core/xwiki-platform-mail/xwiki-platform-mail-test/xwiki-platform-mail-test-docker/src/test/it/org/xwiki/mail/test/ui/MailIT.java"}}MailIT{{/scm}}
110
111 == Example 1: Basic test ==
112
113 {{code language="java"}}
114 @UITest
115 public class SeleniumTest
116 {
117 @Test
118 public void test(XWikiWebDriver driver, TestUtils setup)
119 {
120 driver.get("http://xwiki.org");
121 assertThat(driver.getTitle(),
122 containsString("XWiki - The Advanced Open Source Enterprise and Application Wiki"));
123 driver.findElement(By.linkText("XWiki's concept")).click();
124 }
125 }
126 {{/code}}
127
128 == Example 2: Choosing Container + DB + Browser and versions ==
129
130 {{code language="java"}}
131 @UITest(database = Database.MYSQL, databaseTag = "5", servletEngine = ServletEngine.TOMCAT, servletEngineTag = "8",
132 browser = Browser.CHROME)
133 public class MenuIT
134 ...
135 {{/code}}
136
137 {{code language="java"}}
138 @UITest(database = Database.POSTGRESQL, databaseTag = "9", servletEngine = ServletEngine.JETTY,
139 servletEngineTag = "9", browser = Browser.CHROME)
140 public class MenuIT
141 ...
142 {{/code}}
143
144 {{code language="java"}}
145 @UITest(database = Database.HSQLDB_EMBEDDED, servletEngine = ServletEngine.JETTY_STANDALONE,
146 browser = Browser.FIREFOX)
147 public class MenuIT
148 ...
149 {{/code}}
150
151 == Example 3: Test using Greenmail + Hibernate HBM ==
152
153 {{code language="java"}}
154 @UITest(sshPorts = {
155 3025
156 },
157 properties = {
158 "xwikiDbHbmCommonExtraMappings=mailsender.hbm.xml",
159 // Pages created in the tests need to have PR since we ask for PR to send mails so we need to exclude them from
160 // the PR checker.
161 "xwikiPropertiesAdditionalProperties=test.prchecker.excludePattern=.*:MailIT\\..*"
162 },
163 extraJARs = {
164 "org.xwiki.platform:xwiki-platform-mail-send-storage"
165 }
166 )
167 public class MailIT
168 ...
169 {{/code}}
170
171 == Example 4: Passing Test Configuration ==
172
173 {{code language="java"}}
174 @Test
175 public void verifyMail(TestUtils setup, XWikiWebDriver webDriver, TestConfiguration testConfiguration)
176 throws Exception
177 {
178 ....
179 }
180 {{/code}}
181
182 == Example 5: Specifying explictly dependencies ==
183
184 Example of deploying a ##1.10-SNAPSHOT## version of ##org.xwiki.contrib.latex:latex-export## (and its dependencies) into a ##11.2-SNAPSHOT## version of XWiki. In this example the POM of ##org.xwiki.contrib.latex:latex-export## depends on XWiki 10.2. Thus this example demonstrates running the tests in a more recent version of XWiki than the code was built on.
185
186 {{code language="xml"}}
187 ...
188 <parent>
189 <groupId>org.xwiki.platform</groupId>
190 <artifactId>xwiki-platform</artifactId>
191 <version>11.2-SNAPSHOT</version>
192 </parent>
193 <groupId>org.xwiki.contrib.latex</groupId>
194 <artifactId>latex-test</artifactId>
195 <version>1.10-SNAPSHOT</version>
196 ...
197 <plugin>
198 <groupId>org.apache.maven.plugins</groupId>
199 <artifactId>maven-failsafe-plugin</artifactId>
200 <configuration>
201 <includes>
202 <include>**/AllIT.java</include>
203 </includes>
204 <systemProperties>
205 <xwiki.test.ui.dependencies>org.xwiki.contrib.latex:latex-export</xwiki.test.ui.dependencies>
206 </systemProperties>
207 </configuration>
208 </plugin>
209 {{/code}}
210
211 == Example 6: Passing extension overrides ==
212
213 The following tells the Extension Manager to use the existing core extension ##com.google.code.findbugs:annotations## whenever the extension ##com.google.code.findbugs:jsr305## is requested.
214
215 {{code language="java"}}
216 @UITest(extensionOverrides = {
217 @ExtensionOverride(
218 extensionId = "com.google.code.findbugs:jsr305",
219 overrides = {
220 "features=com.google.code.findbugs:annotations"
221 }
222 )
223 })
224 ...
225 {{/code}}
226
227 Note that in the XWikio build, these extension overrides are defined in the top level XWiki Platform POM and for this specific case it's defined as:
228
229 {{code language="xml"}}
230 ...
231 <extensionOverride>
232 <id>com.google.code.findbugs:jsr305</id>
233 <features>com.google.code.findbugs:annotations</features>
234 </extensionOverride>
235 ...
236 {{/code}}
237
238 Another example:
239
240 {{code language="java"}}
241 ...
242 extensionOverrides = {
243 @ExtensionOverride(
244 extensionId = "org.xwiki.platform:xwiki-platform-web",
245 overrides = {
246 // We set a default UI for the subwiki in the webapp, so that the Wiki Creation UI knows which extension
247 // to install on a subwiki by default (which is something we test)
248 // Otherwise the wiki creation form will display the flavor picker and the functional tests do not handle it.
249 "properties=xwiki.extension.distribution.wikiui=org.xwiki.platform:xwiki-platform-wiki-ui-wiki"
250 }
251 )
252 }
253 ...
254 {{/code}}
255
256 == Example 7: Execute a test on main and subwiki ==
257
258 It can be interresting to verify that a test scenario works both on main and subwiki to catch context related bugs or simply things which were designed too much with main wiki in mind. A @ParameterizedTest source is available to automate this.
259
260 The following example executes the test ##copyPage## twice, once with the main wiki in input and the second time with an automatically created wiki as input and indicate that the extension ##org.xwiki.platform:xwiki-platform-index-tree-macro## is required in the subwiki:
261
262 {{code language="java"}}
263 @ParameterizedTest
264 @WikisSource(extensions = {"org.xwiki.platform:xwiki-platform-index-tree-macro"})
265 void copyPage(WikiReference wiki, TestLocalReference testReference, TestUtils setup, TestConfiguration testConfiguration) throws Exception
266 {
267 ....
268 }
269 {{/code}}
270
271 = Best Practices =
272
273 == Scenarios ==
274
275 Always use scenarios and use JUnit5's ##@Order(...)## annotation. For example:
276
277 {{code}}
278 @UITest
279 public class MenuIT
280 {
281 @Test
282 @Order(1)
283 public void verifyMenuInApplicationsIndex(TestUtils setup)
284 {
285 ...
286 }
287
288 @Test
289 @Order(2)
290 public void verifyMenuCreationInLeftPanelWithCurrentWikiVisibility(TestUtils setup)
291 {
292 ...
293 }
294
295 @Test
296 @Order(3)
297 public void verifyMenuIsAvailableInAdministration(TestUtils setup) throws Exception
298 {
299 ...
300 }
301 }
302 {{/code}}
303
304 == Suites ==
305
306 Use JUnit5's ##@Nested## annotation. For example:
307
308 {{code language='java'}}
309 @UITest
310 public class AllIT
311 {
312 @Nested
313 @DisplayName("Office Import Tests")
314 class NestedOfficeImporterIT extends OfficeImporterIT
315 {
316 }
317
318 @Nested
319 @DisplayName("Office Export Tests")
320 class NestedOfficeExportIT extends OfficeExportIT
321 {
322 }
323 }
324 {{/code}}
325
326 {{version since='12.8RC1'}}
327 When using nested tests, only configure any ##@UITest## parameter in the nested tests themselves and not in the parent (e.g. at the ##AllIT## level the ##@UITest## annotation should be empty). This is because ##@UITest## annotation parameters are automatically merged.
328 {{/version}}
329
330 == Test Reference ==
331
332 A lot of tests need to create a wiki page for testing. Example to do this:
333
334 {{code language="java"}}
335 @Test
336 public void showAndHideEditComments(TestUtils setup, TestReference reference) throws Exception
337 {
338 ViewPage vp = setup.gotoPage(reference);
339 ...
340 {{/code}}
341
342 More generic way (more verbose but can useful in some cases) using JUnit5's ##TestInfo## class:
343
344 {{code language="java"}}
345 public class MailIT
346 {
347 private String testClassName;
348
349 @BeforeEach
350 public void setUp(TestInfo info)
351 {
352 this.testClassName = info.getTestClass().get().getSimpleName();
353 }
354 ...
355 }
356 {{/code}}
357
358 == Docker out of Docker ==
359
360 The [[XWiki's CI>>https://ci.xwiki.org]] is using a [[Jenkins Agent Docker image>>https://github.com/xwiki/xwiki-jenkins-slave]] to execute the job builds. Thus, the Docker-based functional tests spawn Docker containers (using TestContainers) that execute inside Docker. This is the pattern called DOOD (Docker out of Docker). See [[TC's best practice>>https://www.testcontainers.org/supported_docker_environment/continuous_integration/dind_patterns/]] about this.
361
362 There are some consequences when writing tests for XWiki:
363
364 * Never use volume mapping or it won't execute fine. This is because that would require the Jenkins Agent Docker container to have that volume mapping defined too and the mapping would need to use the exact host path and container path. So, in short, it won't work. Instead copy files that you need to have in the container. Adn copy file out if need be. Here's an example from the LaTeX extension on how to achieve this:(((
365 {{code language="java"}}
366 try (GenericContainer container = new GenericContainer("blang/latex:ubuntu")) {
367 // Note: we copy files instead of mounting volumes so that this can work when using DOOD
368 // (Docker out of Docker).
369 MountableFile mountableDirectory = MountableFile.forHostPath("target/latex");
370 container.withCopyFileToContainer(mountableDirectory, "/data");
371
372 container.withCommand("/bin/sh", "-c", "sleep infinity");
373 container.withLogConsumer(new Slf4jLogConsumer(LOGGER));
374 container.start();
375 Container.ExecResult result = container.execInContainer("pdflatex", "-shell-escape", "index.tex");
376 String stdout = result.getStdout();
377 LOGGER.info(stdout);
378 assertTrue(stdout.contains("Output written on index.pdf"));
379
380 container.copyFileFromContainer("/data/index.pdf", "target/latex/index.pdf");
381 }
382 {{/code}}
383 )))
384
385 == Stdout/stderr validation errors ==
386
387 We have a [[check>>Community.Building.WebHome||anchor="HAutomaticChecks"]] that verifies if functional tests output some invalid content to stdout/stderr. If your test contains such errors it'll fail and then you have 3 options:
388
389 * It's a normal and expected output from the test (for ex the test verifies an error condition and it's expected it will raise a stack trace in the console). In this case add an expectation in the test. For example:(((
390 {{code language="java"}}
391 public void wrongTemplate(LogCaptureConfiguration logCaptureConfiguration)
392 {
393 ...
394 logCaptureConfiguration.registerExpected( "Possible break-in attempt!",
395 "Error getting resource [null]");
396 }
397 {{/code}}
398 )))
399 * It's a non-expected error. You then have 2 sub-choices:
400 ** Fix the problem (the best and recommended solution!)
401 ** Increase the technical debt by adding an exclude. For example:(((
402 {{code language="java"}}
403 logCaptureConfiguration.registerExcludes(
404 "java.lang.IllegalStateException: Response is committed");
405 {{/code}}
406 )))
407
408 = Test Resources =
409
410 You might need test resources to be used in interaction with the wiki (e.g. to upload an attachment). Any test resources placed in ##src/test/resources## is made automatically available to the browser container by mounting the dedicated volume mapped to ##target/test-classes##. Then, in your test, you can use the dedicated method to get access to the files located in ##target/test-classes##.
411
412 For example:
413
414 {{code language="java"}}
415 String resourceDirPath = testConfiguration.getBrowser().getTestResourcesPath();
416 File myResourceFile = new File(resourceDirPath, filename);
417 {{/code}}
418
419 = Code Resources =
420
421 You might need custom test code deployed to the XWiki webapp for the test (to override some components for example). Any classes that land into ##target/classes## will be copied to the webapp's ##WEB-INF/classes## directory. Thus you can, for example, put sources in ##src/main/*## to see it deployed in the webapp.
422
423 = Test Logging =
424
425 You might want to activate some debug logs specific to the test. This can be achieved by providing a ##logback-override.xml## file in your ##src/test/resources## directory of your Maven project.
426
427 = Test Coverage =
428
429 Activate support for Clover by setting the ##xwiki.test.ui.profiles## property in the ##clover## profile in the ##pom.xml## file for the test.
430
431 Example:
432
433 {{code language="xml"}}
434 <profiles>
435 <profile>
436 <id>clover</id>
437 <!-- Add the Clover JAR to the WAR so that it's available at runtime when XWiki executes.
438 It's needed because instrumented jars in the WAR will call Clover APIs at runtime when they execute. -->
439 <dependencies>
440 <dependency>
441 <groupId>org.openclover</groupId>
442 <artifactId>clover</artifactId>
443 </dependency>
444 </dependencies>
445 <build>
446 <plugins>
447 <plugin>
448 <groupId>org.apache.maven.plugins</groupId>
449 <artifactId>maven-failsafe-plugin</artifactId>
450 <configuration>
451 <systemProperties combine.children="append">
452 <!-- Tell the Docker-based test to activate the Clover profile so that the Clover JAR is added to
453 WEB-INF/lib -->
454 <property>
455 <name>xwiki.test.ui.profiles</name>
456 <value>clover</value>
457 </property>
458 </systemProperties>
459 </configuration>
460 </plugin>
461 ...
462 {{/code}}
463
464 = Existing XWiki instance =
465
466 If you want to avoid the Docker-based tests to start and stop XWiki every time you re-run the tests (for example when you're developping/debugging something), you can tell the Docker Test framework to not provision an XWiki instance and to use your XWiki instance instead.
467
468 This is achieved by specifying {{code}}@UITest(servletEngine = ServletEngine.EXTERNAL){{/code}} or passing the {{code}}xwiki.test.ui.servletEngine=external{{/code}} system property.
469
470 A common use case is to debug a failing test. Here's what you can do:
471
472 {{code language="none"}}
473 ## Run the test once to see if it fails and to generate the XWiki instance. This may take some time.
474 > mvn clean install -Dit.test=NavigationPanelIT
475 ## Open a new console, look for the generated XWiki instance inside the target folder and start it.
476 ../target/../jetty > start_xwiki.sh
477 ## Modify the test as needed then go back to the initial console and compile the tests.
478 ## Note that you may also need to build the page objects module if you change those too.
479 > mvn compiler:testCompile
480 ## Then run the test again to see the changes. This should be way faster than the initial test run.
481 > mvn failsafe:integration-test -Dxwiki.test.ui.servletEngine=external -Dit.test=NavigationPanelIT
482 {{/code}}
483
484 = Run a single test =
485
486 For example to run the ##NestedResetPasswordIT## tests from an ##AllITs## test class defined as:
487
488 {{code language='java'}}
489 @UITest
490 public class AllITs
491 {
492 @Nested
493 @DisplayName("Overall Administration UI")
494 class NestedAdministrationIT extends AdministrationIT
495 {
496 }
497
498 @Nested
499 @DisplayName("Reset Password")
500 class NestedResetPasswordIT extends ResetPasswordIT
501 {
502 }
503 ...
504 {{/code}}
505
506 You'd use:
507
508 {{code language='none'}}
509 mvn -Dit.test=*NestedResetPasswordIT* clean verify
510 {{/code}}
511
512 See also the [[Existing XWiki instance section>>||anchor='HExistingXWikiinstance']].
513
514 = Architecture =
515
516 {{image reference="xwiki-testcontainers.png"/}}
517 //See [[Vincent's blog>>https://massol.myxwiki.org/xwiki/bin/view/Blog/EnvironmentTestingExperimentations#HExperimentation5:inJavaTestsusingTestContainers]] for more details//
518 )))
519
520 = CI Jobs =
521
522 There are 3 CI jobs executing Docker-based functional tests:
523
524 * [[Job 1>>https://ci.xwiki.org/view/Recommended%20Builds/job/xwiki-platform_docker/]]: run all tests on latest versions of supported configs.
525 * [[Job 2>>https://ci.xwiki.org/view/Recommended%20Builds/job/xwiki-platform_docker_all/]]: run smoke tests (ie a few tests only) on all supported configs.
526 * [[Job 3>>https://ci.xwiki.org/view/Recommended%20Builds/job/xwiki-platform_docker_unsupported/]]: run smoke tests on unsupported configs (MySQL 8.x, Tomcat 9.x, etc) that we want to support in the future.
527
528 Configuration definitions and job sources are all {{scm project="xwiki-jenkins-pipeline" path="vars/dockerConfigurations.groovy"}}here{{/scm}}.
529
530 = Firefox Version Used =
531
532 If you need to know which version of Firefox is used during the Docker-based test execution, do the following:
533
534 * Make sure you have the latest docker image used by TestContainers (replace the version by the version used by XWiki): {{code language="shell"}}docker pull selenium/standalone-firefox:latest{{/code}} (or {{code language="shell"}}docker run seleniarm/standalone-firefox:4.1.3-20220331{{/code}} on ARM)
535 * Start the container: {{code language="shell"}}docker run selenium/standalone-firefox:latest{{/code}} (or {{code language="shell"}}docker run seleniarm/standalone-firefox:4.1.3-20220331{{/code}} on ARM). Note the container id.
536 * Log into the running container: {{code language="shell"}}docker exec -it <container id> bash -l{{/code}}
537 * Ask for the Firefox version: {{code language="shell"}}firefox --version{{/code}}
538
539 Example:
540
541 {{code language="shell"}}
542 [email protected]:/$ firefox --version
543 Mozilla Firefox 92.0.1
544 [email protected]:/$
545 {{/code}}

Get Connected