> Markdown version of [Running Tests with Maven](https://vaadin.com/docs/next/flow/testing/end-to-end/maven). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Running Tests with Maven

A Maven build is divided into different lifecycle phases. Below are the relevant ones:

- `compile` Compiles the code;

- `test` Runs unit tests which don’t require a packaged project;

- `pre-integration-test` Makes preparations for integration tests;

- `integration-test` Executes integration tests; and

- `post-integration-test` Cleans up after integration tests.

TestBench tests fit into the `integration-test` phase. The `pre-integration-test` phase is the place to start a server and deploy the package. The `post-integration-test` phase is where you would stop the server.

> **Note:** Never execute TestBench tests in the `test` phase. They can’t be run without a packaged or deployed project.

\+ If you name your tests `*Test`, they are run automatically in the `test` phase. If you instead name your TestBench tests `*IT`, they’re run automatically in the `integration-test` phase.

## <a id="starting-the-server-automatically"></a>Starting the Server Automatically

For applications without external dependencies, it’s often handy to start a test as part of the build. As an example, if you’re using Jetty to run the project, you can use the `jetty-maven-plugin` to start the server in the `pre-integration-test` and stop it in the `post-integration-test` phase, as follows:

```xml
<plugin>
    <groupId>org.eclipse.jetty.ee10</groupId>
    <artifactId>jetty-ee10-maven-plugin</artifactId>
    <version>12.1.7</version>
    <configuration>
        <stopPort>9966</stopPort>
        <stopKey>something-goes-here</stopKey>
    </configuration>
    <executions>
        <execution>
            <id>start-jetty</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start</goal>
            </goals>
        </execution>
        <execution>
            <id>stop-jetty</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop</goal>
            </goals>
        </execution>
    </executions>
</plugin>
```

The example above uses the EE 10 variant of the Jetty Maven plugin. Choose the variant that matches your project’s Jakarta EE level (e.g., `jetty-ee8-maven-plugin`, `jetty-ee10-maven-plugin`, or `jetty-ee11-maven-plugin`).

The `stopPort` and `stopKey` are Jetty specific parameters which must be given so that Jetty is able to stop the correct server instance. A fully working example of running Jetty as part of the build can be found in <https://github.com/vaadin/testbench-demo/blob/master/pom.xml>.

If you’re using Spring Boot, you can use the `spring-boot-maven-plugin` to achieve the same thing. See the Bakery starter for Spring for an example.

If you’re using JavaEE, you can start TomEE, WildFly or a Liberty server in a similar way. See the Bakery starter for JavaEE for an example — this is available at this time only for Vaadin 8.

## <a id="executing-tests-in-integration-test-phase"></a>Executing Tests in Integration Test Phase

In Maven, unit tests are executed by the `maven-surefire-plugin`, automatically included in all projects. Integration tests are executed by the `maven-failsafe-plugin` instead, which needs to be included manually in the project as the following:

**JUnit 4**

```xml
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>3.5.5</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <trimStackTrace>false</trimStackTrace>
    </configuration>
</plugin>
```

JUnit 5 support is added in Vaadin 24.

**JUnit 5**

```xml
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>3.5.5</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <trimStackTrace>false</trimStackTrace>
        <rerunFailingTestsCount>3</rerunFailingTestsCount>
    </configuration>
</plugin>
```

The `<executions>` part is needed to execute the plugin during the `integration-test` phase. The `<configuration>` part is optional, but by including it you get the full stack trace when an error occurs. This typically makes it easier to determine what went wrong in a test. Running failed tests multiple times is also possible using the `rerunFailingTestsCount` property.

## <a id="webdriver-management"></a>WebDriver Management

Since Selenium 4.6, the built-in [Selenium Manager](https://www.selenium.dev/documentation/selenium_manager/) automatically downloads and manages browser drivers. There’s no need to install or configure drivers manually — instantiating a driver such as `ChromeDriver` takes care of everything. This works both when running tests locally and in CI/CD pipelines.

`2516DA74-34F6-4247-AAD3-44584BF5DBF3`
