Docs

Optimizing Browserless Tests

Speed up browserless tests by restricting package scanning and using reduced application contexts.

By default, browserless tests scan the entire classpath for routes and error views and, in Spring Boot projects, load the full application context. For large projects this can slow down test startup. The following techniques help reduce bootstrap time.

Restricting Package Scanning

To restrict the scan to specific packages and their sub-packages, annotate the test class with @ViewPackages and specify the packages by filling the classes() array with classes that are members of the desired packages, or by providing the packages with fully qualified names in the packages() property. Using classes() is the preferred way, since it plays well with IDE refactoring when moving classes to different packages.

Source code
Package Scan Examples
@SpringBootTest
@ViewPackages(classes={ MyView.class, OtherView.class })
class MyViewTest extends SpringBrowserlessTest {
}

@SpringBootTest
@ViewPackages(packages={ "com.example.app.pgk1", "com.example.app.pgk2" })
class MyViewTest extends SpringBrowserlessTest {
}

@SpringBootTest
@ViewPackages(
    classes={ MyView.class, OtherView.class },
    packages={ "com.example.app.pgk1", "com.example.app.pgk2" }
)
class MyViewTest extends SpringBrowserlessTest {
}

Using the annotation without providing classes() or packages() acts as a shortcut for restricting the scan to the current test class package and sub-packages.

Source code
Java
@SpringBootTest
@ViewPackages // same as @ViewPackages(classes=MyViewTest.class)
class MyViewTest extends SpringBrowserlessTest {
}

Using a Reduced Application Context

Instead of @SpringBootTest, which loads the full application context, you can annotate the test with @ContextConfiguration to provide only the beans needed for the test. This is useful when you want to replace real services with test doubles.

Source code
Java
@ContextConfiguration(classes = ViewTestConfig.class)
class ViewTest extends SpringBrowserlessTest {
    @Test
    public void setText_clickButton_notificationIsShown() {
        final HelloWorldView helloView = navigate(HelloWorldView.class);

        test(helloView.name).setValue("Test");
        test(helloView.sayHello).click();

        Notification notification = find(Notification.class).single();
        Assertions.assertEquals("Hello Test", test(notification).getText());
    }
}

@Configuration
class ViewTestConfig {

        @Bean
        GreetingService myService() {
                return new TestingGreetingService();
        }
}

Sharing the Vaadin Environment Across Tests

By default, the Vaadin environment — the session, the UI, and all routes — is created before every test method and torn down after. For classes with many tests that navigate to views sharing the same MainLayout, this setup cost can dominate the test runtime.

Annotating the test class with @TestInstance(Lifecycle.PER_CLASS) initializes the environment once in @BeforeAll and shares the same UI instance across all test methods in the class. This can significantly reduce runtime for suites with hundreds of tests on the same view.

Source code
Per-Class Lifecycle Example
@ViewPackages(classes = CartView.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CartViewTest extends BrowserlessTest {

    @BeforeAll
    void setup() {
        navigate(CartView.class);
    }

    @Test
    void addItem_increasesCartSize() {
        // same UI instance as the other tests
        test(find(Button.class).withText("Add").single()).click();
    }

    @Test
    void removeItem_decreasesCartSize() {
        // state from the previous test is preserved
    }
}
Warning
With a shared environment, state leaks between tests. Tests must either tolerate leftover state or reset it explicitly — for example, by re-navigating to the view in a @BeforeEach method. Prefer per-class lifecycle for read-only or independent interactions; stick with the default per-method lifecycle when tests mutate shared state in conflicting ways.
Note
This optimization applies only to BrowserlessTest. SpringBrowserlessTest and QuarkusBrowserlessTest still reinitialize the Vaadin environment before each test method, so @TestInstance(PER_CLASS) on those classes doesn’t share the Vaadin environment — though it can still be useful for sharing other per-class state.

A3B7E2F1-5D89-4C6A-9E12-7F4A8B3C6D50

Updated