Testing Java microservices applications
Although it is essential, testing Java apps has become more complicated than ever with the increase of DevOps and new development challenges. Thus, testing strategies need to adapt in order to fit the new realities of microservices. Rod Cope, CTO of Perforce Software, examines how to test Java microservices applications and how to overcome some of the hurdles.
With the wholesale embrace of microservices in Java development, and the increasing influence of the DevOps movement, testing Java applications has never been so complex. Testing strategies developers used for monolithic applications need to be adapted to fit the realities of microservices. Plus, with microservices-based applications promising increased performance and functionality, but also presenting a new series of development challenges, testing has never been so important.
In the past, testing was a largely siloed or individual effort, with those responsible for testing not necessarily involved in coding the application. Likewise, coding an application was done by developers, with performance testing left to dedicated testing teams.
Testing mattered back then, but it matters even more with microservices, where individual services can impact performance in others, as well as in the combined application. With individual developers often working on individual microservices, inter-service performance can be an issue well before an application reaches a traditional testing phase. So, individual containers and the application both need to be continually tested to support successful microservices deployment.
That testing is, in itself, complex. Each service has its own codebase (and possibly written in a different language), database schema, and dependency management, which means spinning up the overall application can take some effort and time. Once that’s all done, it can finally be tested as a whole.
Performance at the forefront
While traditional testing approaches — like unit testing, load testing, and end-to-end functionality testing — still play an important part in application testing, performance has become the focal point for many development teams. Applications need to be able to perform well at scale, so testing performance during development helps teams to see and avoid potential bottlenecks before they cause problems in production.
However, due to the complexity of microservices-based Java applications, these performance issues can be harder to diagnose and fix. To overcome these challenges, development teams need to embrace new ideas and new technologies.
Why test automation is critical – but difficult
The market for automated testing is growing fast, with the promise to help developers overcome those challenges of complexity and scalability (not just in microservices but all kinds of software). Many of the latest automation and testing technologies include features developed specifically for microservices. Kubernetes, Istio, and Jenkins X are a trio that can be used to automate the creation of complex yet disposable environments that lead to better application scalability as well as safer deployment of new production features via canary release.
In theory, once deployed, this level of automation gives Java development teams better control over their application, helping them to produce stable and scalable microservices that work well together. The reality can be a lot more challenging: while it is relatively easy to set up and maintain this automated testing process with a brand-new application, the majority of microservices in play today are being teased out of large monolithic applications.
That makes creating a perfect test environment hard, because of all the legacy elements being dragged along. So while an amount of automated testing can be introduced, some manual testing is still going to be needed. That can mean the test environment becomes fragmented, hard to control, and rife with bottlenecks that undermine successful microservices.
Instilling a DevOps culture for microservices development teams
A shift to microservices often necessitates a shift in development team structure and philosophy. Since there isn’t a singular deployment focus (individual microservices are being continually developed and deployed), there needs to be a consistent approach and a fully-realised set of best practices for developing and testing the application.
Team structure needs to be considered during initial planning — with team leaders considering personalities and skillsets for optimal development efficiency and efficacy. Additionally, a culture of collaboration and cross-service testing (and supporting best practices) need to be instilled in development teams early on.
Increasing visibility for microservices developers
One of the big hurdles for microservices developers is the siloed development structure. A developer working on one microservice may not have insight into another, and late-stage changes in one microservice can necessitate changes to other completed microservices.
Giving developers the tools needed to visualize code impact across microservices can help prevent performance issues during end-to-end testing or production, and prevent late stage, expensive, changes.
While testing has never been more essential, at the same time the techniques and tools available to development teams has never been so rich. Find the right ones for each situation, embrace cultural change as much as technologies and processes, and use these ideas as building blocks for creating a solid Java microservices testing strategy.