UI Integration Tests

Jmix allows you to write tests for the UI layer. In these tests, you can open views, load data, verify the contents of UI components, make modifications, and simulate user actions such as button clicks.

Jmix UI tests start the complete Spring context and can interact with the database like the integration tests of the business logic. They are close to the browser-based end-to-end tests in the sense that they can check a wide range of application functionality, but at the same time they are easy to set up and are executed much faster than browser-based tests.

Every new Jmix project includes an example of a UI integration test: the UserUiTest class that verifies the user management views. Let’s take a look at the configuration and logic of the UI tests using this example.

To execute UI tests, your project should contain the dependency on the jmix-flowui-test-assist module:

build.gradle
testImplementation 'io.jmix.flowui:jmix-flowui-test-assist'

The example test class is shown below.

UserUiTest.java
package com.company.demo.user;

import com.company.demo.DemoApplication;
import com.company.demo.entity.User;
import com.company.demo.view.user.UserDetailView;
import com.company.demo.view.user.UserListView;
import io.jmix.core.DataManager;
import io.jmix.flowui.ViewNavigators;
import io.jmix.flowui.component.UiComponentUtils;
import io.jmix.flowui.component.grid.DataGrid;
import io.jmix.flowui.component.textfield.JmixPasswordField;
import io.jmix.flowui.component.textfield.TypedTextField;
import io.jmix.flowui.data.grid.DataGridItems;
import io.jmix.flowui.kit.component.button.JmixButton;
import io.jmix.flowui.testassist.FlowuiTestAssistConfiguration;
import io.jmix.flowui.testassist.UiTest;
import io.jmix.flowui.testassist.UiTestUtils;
import io.jmix.flowui.view.View;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * Sample UI integration test for the User entity.
 */
@UiTest (1)
@SpringBootTest(classes = {DemoApplication.class, FlowuiTestAssistConfiguration.class}) (2)
public class UserUiTest {

    @Autowired
    DataManager dataManager; (3)

    @Autowired
    ViewNavigators viewNavigators;

    @Test (4)
    void test_createUser() {
        // Navigate to user list view
        viewNavigators.view(UserListView.class).navigate();

        UserListView userListView = UiTestUtils.getCurrentView(); (5)

        // click "Create" button
        JmixButton createBtn = findComponent(userListView, "createBtn"); (6)
        createBtn.click();

        // Get detail view
        UserDetailView userDetailView = UiTestUtils.getCurrentView();

        // Set username and password in the fields
        TypedTextField<String> usernameField = findComponent(userDetailView, "usernameField");
        String username = "test-user-" + System.currentTimeMillis();
        usernameField.setValue(username);

        JmixPasswordField passwordField = findComponent(userDetailView, "passwordField");
        passwordField.setValue("test-passwd");

        JmixPasswordField confirmPasswordField = findComponent(userDetailView, "confirmPasswordField");
        confirmPasswordField.setValue("test-passwd");

        // Click "OK"
        JmixButton commitAndCloseBtn = findComponent(userDetailView, "saveAndCloseBtn");
        commitAndCloseBtn.click();

        // Get navigated user list view
        userListView = UiTestUtils.getCurrentView();

        // Check the created user is shown in the table
        DataGrid<User> usersDataGrid = findComponent(userListView, "usersDataGrid");

        DataGridItems<User> usersDataGridItems = usersDataGrid.getItems();
        Assertions.assertNotNull(usersDataGridItems);

        usersDataGridItems.getItems().stream()
                .filter(u -> u.getUsername().equals(username))
                .findFirst()
                .orElseThrow();
    }

    @AfterEach (7)
    void tearDown() {
        dataManager.load(User.class)
                .query("e.username like ?1", "test-user-%")
                .list()
                .forEach(u -> dataManager.remove(u));
    }

    @SuppressWarnings("unchecked")
    private static <T> T findComponent(View<?> view, String componentId) {
        return (T) UiComponentUtils.getComponent(view, componentId);
    }
}
1 The @UiTest annotation defines a JUnit extension to start Vaadin, configure application views and set up authentication.
2 The @SpringBootTest annotation should declare the application and the jmix-flowui-test-assist module configurations.
3 You can inject any Spring beans using the @Autowired annotation.
4 The test case method.
5 UiTestUtils.getCurrentView() method return the view currently opened by navigation.
6 The findComponent() method returns a UI component by its id.
7 The method executed after each test case can be used for test data cleanup.