Master the most popular testing framework for Java, through the Learn JUnit course:
Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.
Get started with mocking and improve your application tests using our Mockito guide:
Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.
Get started with understanding multi-threaded applications with our Java Concurrency guide:
Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:
Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.
But these can also be overused and fall into some common pitfalls.
To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:
Get started with Spring and Spring Boot, through the Learn Spring course:
>> LEARN SPRINGExplore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:
Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.
I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.
You can explore the course here:
Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.
Get started with Spring Data JPA through the guided reference course:
Refactor Java code safely β and automatically β with OpenRewrite.
Refactoring big codebases by hand is slow, risky, and easy to put off. Thatβs where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.
Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions β one for newcomers and one for experienced users. Youβll see how recipes work, how to apply them across projects, and how to modernize code with confidence.
Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.
1. Introduction
This article is a quick, practical introduction to working with Selenium and writing tests with JUnit and TestNG.
2. Selenium Integration
In this section, weβll start with a simple scenario β opening a browser window, navigating to a given URL and looking for some desired content on the page.
2.1. Maven Dependencies
In the pom.xml file, add the following dependency:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.4.0</version>
</dependency>
The latest version can be found in the Maven Central Repository.
2.2. Selenium Configuration
First, create a new Java class file called SeleniumConfig:
public class SeleniumConfig {
private WebDriver driver;
//...
}
Given weβre using a Selenium 3.x version, we have to specify the path of an executable GeckoDriver file (based on your OS) using a system property called webdriver.gecko.driver The latest version of the GeckoDriver may be downloaded from Github Geckodriver Releases.
Letβs now initialize the WebDriver in the constructor; weβll also set 5 seconds as a time-out for WebDriver to wait for an element on the page to appear:
public SeleniumConfig() {
Capabilities capabilities = DesiredCapabilities.firefox();
driver = new FirefoxDriver(capabilities);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
}
static {
System.setProperty("webdriver.gecko.driver", findFile("geckodriver.mac"));
}
static private String findFile(String filename) {
String paths[] = {"", "bin/", "target/classes"};
for (String path : paths) {
if (new File(path + filename).exists())
return path + filename;
}
return "";
}
This configuration class contains a couple of methods that we will ignore for now, but we will see more about these in the second part of this series.
Next, we will need to implement a SeleniumExample class:
public class SeleniumExample {
private SeleniumConfig config;
private String url = "http://www.baeldung.com/";
public SeleniumExample() {
config = new SeleniumConfig();
config.getDriver().get(url);
}
// ...
}
Here, we will initialize the SeleniumConfig and set the desired URL to navigate to. Similarly, weβll implement a simple API to close the browser and get the title of the page:
public void closeWindow() {
this.config.getDriver().close();
}
public String getTitle() {
return this.config.getDriver().getTitle();
}
In order to navigate to the About section of baeldung.com, we need to create a closeOverlay() method that checks and closes the overlay on a homepage load. Thereafter, we navigate to the About Baeldung page using the getAboutBaeldungPage() method:
public void getAboutBaeldungPage() {
closeOverlay();
clickAboutLink();
clickAboutUsLink();
}
private void closeOverlay() {
List<WebElement> webElementList = this.config.getDriver()
.findElements(By.tagName("a"));
if (webElementList != null) {
webElementList.stream()
.filter(webElement -> "Close".equalsIgnoreCase(webElement.getAttribute("title")))
.filter(WebElement::isDisplayed)
.findAny()
.ifPresent(WebElement::click);
}
}
private void clickAboutLink() {
Actions actions = new Actions(config.getDriver());
WebElement aboutElement = this.config.getDriver()
.findElement(By.id("menu-item-6138"));
actions.moveToElement(aboutElement).perform();
}
private void clickAboutUsLink() {
WebElement element = this.config.getDriver()
.findElement(By.partialLinkText("About Baeldung."));
element.click();
}
We can check if the required information is available on the displayed page:
public boolean isAuthorInformationAvailable() {
return this.config.getDriver()
.getPageSource()
.contains("Hey ! I'm Eugen");
}
Next, we are going to test this class with both JUnit and TestNG.
3. With JUnit
Letβs create a new test class as SeleniumWithJUnitLiveTest:
public class SeleniumWithJUnitLiveTest {
private static SeleniumExample seleniumExample;
private String expectedTitle = "About Baeldung | Baeldung";
// more code goes here...
}
Weβre going to use the @BeforeClass annotation from org.junit.BeforeClass to do an initial setup. In this setUp() method, we are going to initialize the SeleniumExample object:
@BeforeClass
public static void setUp() {
seleniumExample = new SeleniumExample();
}
In a similar way, when our test case finishes, we should close the newly opened browser. Weβre going to do this with @AfterClass annotation β to clean up the settings when the test case execution has finished:
@AfterClass
public static void tearDown() {
seleniumExample.closeWindow();
}
Please note the static modifier on our SeleniumExample member variable β because we need to use this variable in the setUp() and tearDown() static methods β @BeforeClass and @AfterClass can be invoked on static methods only.
Finally, we can create our full test:
@Test
public void whenAboutBaeldungIsLoaded_thenAboutEugenIsMentionedOnPage() {
seleniumExample.getAboutBaeldungPage();
String actualTitle = seleniumExample.getTitle();
assertNotNull(actualTitle);
assertEquals(expectedTitle, actualTitle);
assertTrue(seleniumExample.isAuthorInformationAvailable());
}
This test method asserts that the title of the web page is not null and is set as expected. Besides that, we check that the page contains the expected information.
When the test runs, it simply opens the URL in Firefox and subsequently closes it after the title of the web page and content have been verified.
4. With TestNG
Letβs now use TestNG to run our test case/suite.
Note that if youβre using Eclipse, the TestNG plugin may be downloaded and installed from the Eclipse Marketplace.
First, letβs create a new test class:
public class SeleniumWithTestNGLiveTest {
private SeleniumExample seleniumExample;
private String expectedTitle = "About Baeldung | Baeldung";
// more code goes here...
}
Weβll use a @BeforeSuite annotation from org.testng.annotations.BeforeSuite to instantiate our SeleniumExample class. The setUp() method will be launched just before the test suite is activated:
@BeforeSuite
public void setUp() {
seleniumExample = new SeleniumExample();
}
Similarly, weβll use the @AfterSuite annotation from org.testng.annotations.AfterSuite to close our opened browser once the test suite has been completed:
@AfterSuite
public void tearDown() {
seleniumExample.closeWindow();
}
Finally, letβs implement our test:
@Test
public void whenAboutBaeldungIsLoaded_thenAboutEugenIsMentionedOnPage() {
seleniumExample.getAboutBaeldungPage();
String actualTitle = seleniumExample.getTitle();
assertNotNull(actualTitle);
assertEquals(expectedTitle, actualTitle);
assertTrue(seleniumExample.isAuthorInformationAvailable());
}
After successful completion of the test suite, we find HTML and XML reports in the test-output folder of the project. These reports summarize the test results.
5. Conclusion
In this quick article, weβve focused on a quick intro to writing Selenium 3 tests with both JUnit and TestNG.
