Considerations for a Java-based Test Automation Framework — Part 2

Venkat S
4 min readApr 30, 2023

This is a continuation of a 2 part of series. If you haven't read the first part already, you can read it here.

In the first part, we looked at the importance and selection of language, automation tools, build automation, source control, etc. Let us look at a few more components that are important for building a robust framework.

Consideration 6 — File Readers and Connections

If you have done coding before, you must know by now that not all data related to your code is hard-coded into the code itself (if you are doing it, this is wrong!). There are several benefits of having reusable data in a central place, the foremost of which is — when something changes you don’t have to modify it at multiple places.

Examples of data that are maintained separately are Environment Data, User Credentials, URLs, etc. There are several ways to store and manage this data. The common ways are using:

  • Property files
  • Excel documents
  • Database

Java provides in-built I/O functions to read from Property files. For data stored in a database, you will have to implement a JDBC connection to read/write data. And for Excel documents, you will depend on an external library like Apache POI for interactions. You will have to consider these when setting up the framework.

Sample Test with JDBC Connection

Consideration 7 — Loggers

System.out.println("Hello world”); will probably be the first program any Java programmer will write. This is carried forward as we progress and even in complex programs running complex applications, the print statements are still being used to print information to the console.

There is nothing wrong with this approach (unless we are overdoing it) but this information is not retained and is not shareable. If you wanted to have information (or in other words, ‘logs’) written somewhere where it will not be lost or overwritten, you use a logger framework. Having logs is very important in any software development, including test automation because it helps in debugging issues and failures.

The common loggers used are log4j and slf4j. These utilities help us write information from tests (e.g. test name, assertions, callouts, etc.) into a file with timestamps. There are a lot of configurations you can play with here, but overall having a logger component for your framework is important for the above reasons.

Sample Logs from Log4j

Consideration 8 — Reporting

We have seen in previous sections about testing frameworks like JUnit and TestNG and reporting capabilities they provide. TestNG produces better reports of the two, with an HTML version that can be hosted on a server or shared with stakeholders for reviewing results.

If you want to take this to a next level, you can also consider integrating a reporting utility like Extent or Allure reports, to get a better-looking report with more features/functionality e.g. adding screenshots. This is just an enhancement step and optional if you are good with the reports generated by TestNG.

Let us step into some advanced topics now, having covered the basics so far.

Consideration 9 — Test Environment

When you have your framework and start building your tests, it is fine running the tests on your local machine initially. But soon, the number of tests increases in size, and running them all on your local machine/browser becomes extremely challenging.

If tests are run sequentially, it is going to lot of time to complete a suite. For running in parallel you need hardware strong enough to support all the load. The solution to this is running the tests remotely — virtual machines, docker, or cloud.

Running tests on docker containers with selenium-grid is gaining more traction these days given its simplicity, being open-source, and support from the community. If setting up and maintaining the infrastructure is too complex for you, the other options are using paid cloud partners like BrowserStack, SauceLabs, Perfecto, Digital.ai, etc.

Setting up your environment on cloud providers like AWS and Azure DevOps is also an option for enterprise-level automation efforts.

Sample Docker Setup with Selenium Grid

Consideration 10 — CI/CD

CI/CD stands for Continuous Integration and Continuous Delivery. This includes automating a cycle of events from building the code to deploying the application. This is a high level of what a CI/CD pipeline might look like — The developer writes the code and commits to a code repository, the code is built, automated tests are run, the application gets deployed and test results are published.

This has become almost an essential part of test automation frameworks at an enterprise level for the multiple benefits it offers in determining software quality and providing results quickly. We will not go into the details of those benefits in this article, but it is something worth investing time in understanding.

Some common tools used for CI/CD are Jenkins, Azure DevOps, and more recently Github Actions is gaining some traction. There are also other providers like Bamboo, and Travis CI.

Sample Test Run with GitHub Actions

And that concludes the 2-part series on considerations for a Java-based test automation framework. Did I miss something? Let me know in the comments.

--

--