DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • MVP Product Costing $100,000+ Without QA Testing. Is It Possible?
  • Maximizing Efficiency With the Test Automation Pyramid: Leveraging API Tests for Optimal Results
  • Solid Testing Strategies for Salesforce Releases
  • Running and Debugging Tests With Playwright UI Mode

Trending

  • It’s Not About Control — It’s About Collaboration Between Architecture and Security
  • How Large Tech Companies Architect Resilient Systems for Millions of Users
  • AI’s Role in Everyday Development
  • Performing and Managing Incremental Backups Using pg_basebackup in PostgreSQL 17
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Testing Swing Application

Testing Swing Application

In this article, look at testing Swing application with AssertJ, JUnit5, and GitHub Action based on an example of a GUI application for the Posmulten library.

By 
Szymon Tarnowski user avatar
Szymon Tarnowski
DZone Core CORE ·
Nov. 29, 23 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
4.1K Views

Join the DZone community and get the full member experience.

Join For Free

I had to recently add UI tests for an application implemented with Swing library for the Posmulten project. The GUI does not do any rocket science. It does what the Posmulten project was created for, generating DDL statements that make RLS policy for the Postgres database, but with a user interface based on Swing components. Now, because the posmulten is an open-source project and the CI/CD process uses GitHub action, it would be worth having tests covering the UI application's functionality. Tests that could be run in a headless environment.

Testing Framework

As for testing purposes, I picked the AssertJ Swing library. It is effortless to mimic application users' actions. Not to mention that I could, with no effort, check application states and their components. 

Below is an example of a simple test case that checks if the correct panel will show up with the expected content after entering text and clicking the correct button.

Java
 
    @Test
    public void shouldDisplayCreationScriptsForCorrectConfigurationWhenClickingSubmitButton() throws SharedSchemaContextBuilderException, InvalidConfigurationException {
        // GIVEN
        String yaml = "Some yaml";
        ISharedSchemaContext context = mock(ISharedSchemaContext.class);
        Mockito.when(factory.build(eq(yaml), any(DefaultDecoratorContext.class))).thenReturn(context);
        List<SQLDefinition> definitions = asList(sqlDef("DEF 1", null), sqlDef("ALTER DEFINIT and Function", null));
        Mockito.when(context.getSqlDefinitions()).thenReturn(definitions);
        window.textBox(CONFIGURATION_TEXTFIELD_NAME).enterText(yaml);

        // WHEN
        window.button("submitBtn").click();

        // THEN
        window.textBox(CREATION_SCRIPTS_TEXTFIELD_NAME).requireText("DEF 1" + "\n" + "ALTER DEFINIT and Function");
        // Error panel should not be visible
        findJTabbedPaneFixtureByName(ERROR_TAB_PANEL_NAME).requireNotVisible();
    }


You can find the complete test code here.

Posmulten

The library for which the GUI application was created is generally a simple DDL statement builder that makes RSL policy in the Postgres database. The generated RLS policies allow applications communicating with the Postgres database to work in Mutli-tenant architecture with the shared schema strategy. 

For more info, please check below links:

  • Posmulten
  • GUI module
  • Shared Schema Strategy With Postgres
  • Multi-tenancy Architecture With Shared Schema Strategy in Webapp Application Based on Spring-boot, Thymeleaf, and Posmulten-hibernate

Maven Configuration

It is worth excluding UI tests from unit tests. Although tests might not be fully e2e with mocked components, it is worth excluding from running together with unit tests because their execution might take a little longer than running standard unit tests.

XML
 
<profile>
            <id>swing-tests</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.gmavenplus</groupId>
                        <artifactId>gmavenplus-plugin</artifactId>
                        <version>1.5</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>compile</goal>
                                    <goal>testCompile</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>2.22.1</version>
                        <configuration>
                            <includes>
                                <include>**/*SwingTest.java</include>
                            </includes>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>


Full Maven file.

To run tests locally, on an environment with a Graphics card, you need to execute tests with a maven wrapper, like below.

Shell
 
./mvnw -pl :openwebstart '-DxvfbRunningTests=true' -P !unit-tests,swing-tests test


GitHub Action

Now, moving to the GitHub action, running the UI test on the environment with a Graphics card seems easy. However, there might be situations when some UI windows with a WhatsApp or MS Teams notification appear on the Desktop on which UI tests are executed, and our tests will fail. Tests should be repeated in such cases, but that is not the problem.

Many more problems can occur when we try to execute tests on a headless environment, which is probably the default environment for every CI/CD pipeline. And we still need to run those tests and ensure they will pass no matter if they are executed in such an environment.

When we ask how to execute UI tests in a headless environment, the first suggestion on the internet is to use the Xvfb. However, the contributors of AssertJ Swing suggest a different approach.

Our tests maximize windows and do other stuff the default window manager of xvfb doesn't support. TightVNC makes it easy to use another window manager. Just add gnome-wm & (or the window manager of your choice) to ~/.vnc/xstartup and you're ready to run.

GitHub

So, I followed suggestions from the contributors' team and used the Tightvncserver. I had some problems with adding the gnome-wm. Instead, I used the Openbox.

Below, you can see the step that runs UI tests.

The full GitHub action file can be found here.

The script files used to configure CI can be found here.

YAML
 
  testing_swing_app:
    needs: [compilation_and_unit_tests, database_tests, testing_configuration_jar]
    runs-on: ubuntu-latest
    name: "Testing Swing Application"
    steps:
      - name: Git checkout
        uses: actions/checkout@v2

        # Install JDKs and maven toolchain
      - uses: actions/setup-java@v3
        name: Set up JDK 11
        id: setupJava11
        with:
          distribution: 'zulu' # See 'Supported distributions' for available options
          java-version: '11'
      - name: Set up JDK 1.8
        id: setupJava8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - uses: cactuslab/maven-toolchains-xml-action@v1
        with:
          toolchains: |
            [
            {"jdkVersion": "8", "jdkHome": "${{steps.setupJava8.outputs.path}}"},
            {"jdkVersion": "11", "jdkHome": "${{steps.setupJava11.outputs.path}}"}
            ]
      - name: Install tightvncserver
        run:  sudo apt-get update && sudo apt install tightvncserver
      - name: Install openbox
        run:  sudo apt install openbox
      - name: Copy xstartup
        run:  mkdir $HOME/.vnc && cp ./swing/xstartup $HOME/.vnc/xstartup && chmod +x $HOME/.vnc/xstartup
      - name: Setting password for tightvncserver
        run:  ./swing/setpassword.sh
      - name: Run Swing tests
        id: swingTest1
        continue-on-error: true
        run:  ./mvnw -DskipTests --quiet clean install && ./swing/execute-on-vnc.sh ./mvnw -pl :openwebstart '-DxvfbRunningTests=true' -P !unit-tests,swing-tests test
        #https://www.thisdot.co/blog/how-to-retry-failed-steps-in-github-action-workflows/
#        https://stackoverflow.com/questions/54443705/change-default-screen-resolution-on-headless-ubuntu
      - name: Run Swing tests (Second time)
        id: swingTest2
        if: steps.swingTest1.outcome == 'failure'
        run:  ./mvnw -DskipTests --quiet clean install && ./swing/execute-on-vnc.sh ./mvnw -pl :openwebstart '-DxvfbRunningTests=true' -P !unit-tests,swing-tests test


Retry Failed Steps in GitHub Action Workflows

As you probably saw in the GitHub action file, the last step, which executes the UI tests, is added twice. After correctly setting up Tightvncserver and Openbox, I didn't observe that the second step had to be executed, except at the beginning during deployment when there were not a lot of UI components. I used Xvfb, and sometimes, the CI passed only after the second step. So even if there is no problem with executing the test the first time right now, then it is still worth executing those tests the second time in case of failure. To check if the first step failed, we first have to name it. In this case, the name is "swingTest1". In the second step, we use the "if" property like the below:

YAML
 
if: steps.swingTest1.outcome == 'failure'


And that is generally all for running the step a second time in case of failure.

Check this resource if you want to check other ways to execute the step a second time.

Summary

Setting CI for UI tests might not be a trivial task, but it can benefit a project with any GUI. Not all things can be tested with unit tests. 

GitHub UI application Testing Swing Application Framework

Opinions expressed by DZone contributors are their own.

Related

  • MVP Product Costing $100,000+ Without QA Testing. Is It Possible?
  • Maximizing Efficiency With the Test Automation Pyramid: Leveraging API Tests for Optimal Results
  • Solid Testing Strategies for Salesforce Releases
  • Running and Debugging Tests With Playwright UI Mode

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!