Skip to main content

Search...

Software Testing with Java: JUnit, WireMock, and Selenium

Software testing with Java follows the test pyramid, from unit tests in milliseconds to UI tests that take minutes. Maven controls what runs when.

• • Updated: • 9 min read
Cover of the expert talk on 'Software Testing with Java: JUnit, WireMock, and Selenium' with Pascal Moll and Richard Seidl.

Getting started with software testing and test automation in Java begins with the test pyramid: unit tests, integration tests, API tests and UI tests form levels of rising complexity and runtime. Tools such as JUnit, WireMock, Selenium and Maven cover the individual levels. Behavior Driven Development links technical tests to plain-language descriptions in the Given-When-Then format.

Key Takeaways

  • Unit tests in Java run in milliseconds and are often written by the developers themselves, while UI tests with Selenium already take minutes and use far more resources.
  • Test automation costs electricity as well as staff time: anyone running 25 browsers in different versions in parallel has to weigh that effort against what actually needs testing.
  • Maven manages more than dependencies. It also decides which tests run in which step of the build pipeline, which gives testers direct control over the test suite.
  • According to Pascal Moll, Behavior Driven Development also helps with test data management: data tables can sit directly in Gherkin feature files, and for large amounts of data CSV files are the better choice.

What Testing Is About Before Java Comes In

Testing is not one thing. The single word covers dozens of ways to check a system, and getting started with Java testing only works once the basic concepts are clearly separated. People coming from development, or starting with no programming background at all, tend to trip over exactly this: which type of test fits when, and do you even need to know how to code?

A basic grasp of testing concepts and of test automation carries over to any programming language. The concepts work in Java just as they do in Python. Only the syntax changes. Java is still one of the most widely used languages, so it is worth walking through the abstract ideas once in concrete Java terms.

The Test Pyramid in Java: From Milliseconds to Minutes

The test pyramid sorts test types by breadth and runtime, and in the Java world it has the classic shape. The widest level sits at the bottom, the narrowest at the top, and above it floats something that does not fit any fixed form.

Unit tests form the base. They break the software down into individual units, take a few minutes to write and run in milliseconds. In many projects, developers write these tests themselves because they are quick and work directly on the code.

One level up, components are put together. This is where integration testing starts, followed by system tests, with acceptance tests at the top. The system under test grows with each level, and so does the runtime. UI tests, the classic at the top, already take minutes.

A cloud hovers above the pyramid: exploratory testing. It follows no fixed automation structure and adds to what the automated levels cover.

Which Tools Cover Java Testing at Each Level

Every level of the pyramid has established tools in Java. JUnit is the standard framework for unit tests and has counterparts in other languages, such as NUnit in C#. The principle stays the same. Only the name changes.

One level up, for API tests, mocking comes in as soon as an interface is not fully available yet. WireMock is a common tool for simulating the missing components. UI tests run on Selenium. If you want to describe and check the behavior of the software in natural language, you end up with Behavior Driven Development, which can pull in API tests and other levels.

This overview maps the main tools to their jobs:

Level / TaskTool
Unit testsJUnit
API tests with mockingWireMock
UI testsSelenium
Describing behaviorBehavior Driven Development (Gherkin feature files)
Managing librariesMaven

Maven Is More Than a Library Manager

Maven runs the whole build lifecycle and makes test code easier to handle. The lifecycle has several steps, and each of them can be configured. The very first step, validate, checks whether the configuration is valid at all before anything else runs.

At its core, Maven builds the code. It compiles, checks that everything is configured correctly and pulls in external libraries or parameters. Because most test tools already exist as libraries, you can add them this way instead of wiring them in by hand.

In the end, you decide which tests run. The full suite, a few individual tests or only the integration tests: all of it is set in the configuration. That makes Maven a practical tool once the test base starts to grow.

Testers and Developers Look at the Same Code Differently

The biggest difference when testing Java code is the perspective, not the language. People who write code think about readability and maintainability first. Edge cases and pitfalls easily slip out of view.

A tester flips the question: what happens with invalid values? Does the software crash, or does it handle the error cleanly? That perspective belongs right in the Java code, for example through exception handling.

Error messages are something to test in their own right. You check whether an exception is thrown at all, whether it shows up in the right place and whether something unexpected happens instead. Testing exceptions is a field of its own, not a by-product.

How Test Data Is Managed in Java Tests

Java offers several ways to handle test data, and the right one depends on how much data you have. In Behavior Driven Development, data can go straight into the feature files. Those files are written in natural language following the Given-When-Then pattern: given a situation, such as an open browser, when a button is clicked, then an action follows.

Inside these Gherkin scenarios, data tables are the most common way to supply test data. They sit directly in the feature file and are available to the test. That works well as long as the amount of data stays manageable.

Once the data goes beyond roughly a hundred rows, tables in the feature file get hard to read. CSV files that the test simply loads are the better fit then. For larger or dynamic data sets, you can also connect a database.

Why Sustainability Belongs in Test Planning

Testing costs electricity as well as staff time, and that changes the question of how much to test. Every test case and every build pipeline uses energy and money. Running a lot of test cases affects both your own budget and the environment.

That is why it pays to be clear about the goal of each test up front. Where human lives are at stake, the focus is different from checking a web form. Priorities shift, and so does the question of which test cases are really needed.

Java matters here because it can be resource-hungry. UI testing can be pushed endlessly, for example with 25 browsers in different versions running in parallel. That has a price. Thinking these expansion steps through in advance saves resources before they are spent.

“There is so much knowledge in it that you can build on it. Once you have read it, you have a basic understanding and can decide which direction to take next.”

(Pascal Moll)

Frequently Asked Questions

Do you need programming skills to get started with software testing?

No. A basic understanding of testing concepts is essential regardless of the programming language: unit, integration, system, and acceptance tests work according to the same principles in Java as they do in Python; only the syntax differs. Whether you come from a development background or are starting without any programming experience, you should first clearly distinguish between the different test types. Java is a good language to practice with because it’s widely used.

How much do unit tests and UI tests differ in runtime?

By orders of magnitude. Unit tests run in milliseconds and can be written in a few minutes, while UI tests using Selenium take several minutes and consume significantly more resources. The reason lies in the scope of the system being tested: With each level of the test pyramid, the scope of what’s being tested expands, from the individual unit to the acceptance test.

Where do exploratory tests fit into the test pyramid?

They exist outside the fixed structure. A cloud hovers above the pyramid: exploratory testing, which does not follow any automation structure and complements what the automated levels cover. Thus, it does not replace either unit or UI tests, but rather steps in where tests cannot be captured in scripts.

When is mocking useful in API testing?

As soon as an interface is not yet fully available. In that case, a mock simulates the missing component so the test can still run. WireMock is a common tool for this in the Java environment. For the remaining stages, the same logic applies: use established libraries: JUnit for unit tests and Selenium for UI tests.

How does a build tool like Maven support testing?

It does more than just integrate libraries. Maven manages the entire build cycle and determines which tests run at which stage of the pipeline: the complete suite, individual tests, or exclusively integration testing. The first step, “validate”, checks in advance whether the configuration is even valid. Since most testing tools are available as libraries, they can be integrated directly.

How does a tester’s perspective on Java code differ from that of a developer?

It’s the line of questioning. When writing code, one thinks first of readability and maintainability, and edge cases can easily be overlooked. A tester looks for invalid values and checks whether the software crashes or catches the error cleanly. Error messages themselves are the subject of testing: whether an exception occurs, appears in the correct place, and nothing unexpected happens.

At what data volume should test data be moved out of the feature files?

Around one hundred lines. Data tables directly within the Gherkin feature file are the most common way to specify test data and work well as long as the volume remains manageable. Beyond that, they become cluttered, so CSV files that the test loads are a better option. For larger or dynamic datasets, databases can be integrated.

Share this page