How Developers Use Synthetic Data for Accelerated Unit Testing
The strategy of Shifting left means performing software testing earlier in the SDLC so that defects can be detected when they are faster and easier to correct. Software bugs that escape to production can cost 100 times more to resolve than early in the product lifecycle.
Shift Left means involving developers in the testing process and encouraging them to focus on quality at the earliest possible stage of the software build process. Unit Testing is the earliest stage in the software release pipeline where software defects can be caught and eliminated before they progress to later stages.
Because unit testing is the most frequently performed category of testing, it’s an ideal candidate for automation. Tools like JUnit, NUnit and TestNG have become popular frameworks for automated unit testing and all of these tools can operate even more efficiently when combined with GenRocket’s Test Data Automation (TDA) technology.
In this article we’ll explain how developers can automate the generation of synthetic test data for unit tests integrated into a CI/CD release pipeline. We’ll provide a simple example of how GenRocket’s Test Data Generation engine can be called during test execution and generate real-time synthetic data to validate the code during automated Unit Testing.
How GenRocket Complements Unit Testing
The first step is to design the volume and variety of test data required to simulate the target data environment with GenRocket’s self-service platform. Synthetic data can be designed at different levels of complexity depending on the requirements of the test and can be organized as a hierarchy of executable files, such as:
- Scenarios or Scenario Chains that define the required synthetic data generators
- Test Data Cases that apply rules for controlling and conditioning the data
- Chapters, Stories and Epics that aggregate multiple Test Data Cases and Scenarios
These executable design files contain information used by the GenRocket Runtime Engine to generate synthetic data that is always fresh, accurate and referentially intact. GenRocket allows the developer to generate simple or complex forms of synthetic test data as needed to maximize coverage or to simulate various data loads.
The test script below is a Groovy Class that specifies a simple load test for a hypothetical unit of code. This simple test uses a familiar Given-When-Then structure to outline the test flow. Lines #3-4 contain the libraries that will be imported and used by the test. Line #10 is a statement that instantiates an API that will be used to trigger real-time synthetic test data generation by the GenRocket Runtime Engine. This synthetically generated data will be used to load-test the code.
Lines #15-16 contain API calls to retrieve pre-configured test data design files from a GenRocket resource known as G-Repository, a continuously synchronized storage area for users of the GenRocket platform. “BankDemo” is a folder that contains a Test Data Project for generating referentially intact synthetic data for a banking application.
“RootTableEpic” is a GenRocket Epic that is loaded from the Bank Demo project. This Epic is an aggregation of Stories, Cases and Scenarios that contain the pre-selected and pre-configured data generators to produce realistic and referentially intact synthetic data for our load test. The Epic (and its Scenarios and Test Data Cases) specify the precise volume and variety of data to be generated by the GenRocket Runtime Engine.
At this point, our scripted Unit Test has defined, loaded, and run the Scenarios and Test Data Cases needed to populate the data tables for load-testing the code. A counter (line #19) tracks the test data that is being injected. The test will validate 10,000 rows of data are properly inserted into the appropriate data tables. This completes the “Given” section of our test script.
The next section (the “When” section) inserts data one row at a time until all 10,000 rows have been loaded. In line #22 we illustrate a second method for calling the GenRocket Runtime Engine and triggering the test data generation process. It uses a command line method to specify the location of specific test data scenarios and cases to be run.
The final section of the script (the “Then” section) contains the assertion test to validate the test result confirming all 10,000 rows were successfully inserted into the application.
Flexible DevOps Integration
GenRocket can integrate its Test Data Automaton platform into any DevOps environment. Our sample Unit Test is written in Groovy and compiles to a standard Java executable file. This provides compatibility with any testing tool or framework that supports Java.
The diagram below illustrates an Azure pipeline with a test runner for scheduling a variety of automated tests. One of those tests processes is our sample Unit Test executed by JUnit which in turn, calls the GenRocket Runtime Engine to execute Test Data Cases that generate synthetic data for load testing.
There are many ways that GenRocket can integrate into CI/CD pipelines within an Azure, Google Cloud, Amazon Web Services, or other cloud-based environment. GenRocket Test Data Cases and Scenarios can be launched using any of the following methods:
- Command line
- Batch file
- Shell scripts
- Scripting language
- Bash file (e.g., for Jenkins)
- Compiled language
- REST API
- Socket API
- GMUS (GenRocket’s Multi-User Server)
These integration methods provide developers and testers with many options for integrating GenRocket with virtually any toolset for software development and testing.
A New and Different Approach for Unit Testing
The simple Unit Testing example illustrates a powerful paradigm shift for software developers. With GenRocket, developers are empowered to define and generate the data needed for testing at moment they are ready to develop and build each new unit of code. There is no longer a need to create data manually or to rely on spreadsheets. And there is no need to requisition test data from a production environment. No one knows what volume or variety of data will provide the most comprehensive test of the code better than its developer.
GenRocket enhances the developer experience by accelerating the Unit Testing process as it ensures the highest quality code. And the benefits of high-quality unit testing will compound as the components of an application are integrated into complete systems and released to production at a faster pace and with fewer defects.