Optimizing Browserless Tests
- Restricting Package Scanning
- Using a Reduced Application Context
- Sharing the Vaadin Environment Across Tests
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