by: Shamim Ahmed
Service virtualization (SV) has evolved as a popular technique and technology over the last decade. Traditionally, SV has primarily been used by testers to simulate other application components that the application under test interacts with. Typically, virtual services have been created and maintained by center of excellence (COE) teams.
This meant that such efforts were often isolated from other personas, such as developers, test data engineers, deployment engineers, release engineers, and so on. For example, developers typically use programmatic techniques (such as mocking and stubbing) to support their unit and component testing efforts, and such assets are not re-useable by testers (and vice-versa). Similarly, test data engineers fail to leverage the synergies between virtual services and test data. In addition, deployment engineers fail to leverage virtual services to simplify and automate the provisioning and deployment of their environments.
With the increased adoption of DevOps, continuous integration (CI), continuous delivery (CD), and continuous testing (CT) practices, SV activities can’t continue to be performed in isolation, as they traditionally have been. It is imperative to integrate SV efforts with other activities in the CI/CD/CT/DevOps lifecycle to enable better collaboration and frictionless agility. This new approach to SV is what we call “continuous SV.”
This is the first of a two-part series of blog posts on continuous SV. In this blog, we will describe some best practices for establishing continuous SV as part of DevOps. In our second post, Continuous Service Virtualization, Part 2: Steps for Optimizing DevOps, we will discuss four key steps for leveraging continuous SV to optimize collaboration and flow in the DevOps lifecycle.
“Continuous” SV is derived from the principle of “continuous everything” in DevOps. Continuous SV is a key component of CD within the DevOps framework. With this approach, SV activities are embedded across the different phases of the CI/CD lifecycle, as opposed to being employed in a single “testing phase.” SV activities are performed collaboratively by different personas, such as developers, API engineers, testers, deployment engineers, and so on. As assets are progressively built and maintained, they are shared by these different teams. (See figure 1 below.)
Figure 1: Continuous SV concept
The following are the key practices that enable continuous SV.
As with most activities in the CI/CD lifecycle, continuous SV also requires that most of the SV work (such as specification of virtual services, and virtual service generation, updates, and maintenance) “shifts left,” so it happens mostly during the CI part of the DevOps lifecycle. This minimizes the delay that SV processes can cause during the CD part of the lifecycle, helping to speed deployment cycle time. (See figure 2 below.) We will describe what SV activities happen in each stage of the lifecycle later in this blog.
Figure 2: Continuous SV along the CI/CD pipeline
The test pyramid is one of the key tenets of shifting testing left. This means that more and more SV processes need to support tests in the lower half of the pyramid, for example unit, component, integration, and component tests. (See figure 3 below.)
Figure 3: Mapping types of virtual services into the test pyramid
This also influences the type of SV approach we use:
Note that the test pyramid applies not just to functional tests, but performance tests as well. The reason we point this out is that virtual services play a key role in performance testing at all levels. It does so by emulating not just the functionality of the endpoint, but also the performance of the dependent endpoint, so that the performance of the target application can be tested completely.
To map the needs of virtual services to the test pyramid, we need to use “progressive virtualization” (see figure 4 below). Progressive virtualization means that we first build simple lightweight synthetic virtual services (which are the easiest to create) for the development/unit test part of the CI/CD lifecycle. As we move from left to right along the lifecycle, our virtual services progressively become more realistic to support the latter stage tests—using more robust test data scenarios and/or using recorded virtualization for services that have been implemented by that stage.
Figure 4: Progressive virtualization
This is different than the traditional mocks and stubs that developers create for unit testing. These traditional elements are often not re-used by testers (for latter stage tests) or by other developers. On the other hand, in the case of progressive virtualization, the same lightweight virtual services are progressively (or continuously) enhanced, re-used, and shared with multiple teams, which improves the productivity of all teams.
Re-use of virtual services in progressive virtualization, as described above, is supported by the use of an integrated service catalog and gateway (See figure 5 below). An SV catalog provides a centralized repository for sharing and managing virtual services across teams and applications. In addition, using a gateway allows parameterized access from clients to different versions of the virtual service (or a real service if available, for example in pre-production testing) without changing the client code.
Figure 5: Continuous SV with Service Catalog
Continuous test data management is a key practice for enabling CT. When complemented with test data, virtual services enable tests to be more robust in their ability to support a greater range of scenarios and interactions with the simulated endpoint.
In fact, the type of test data used (whether synthetic, hybrid, or production-like) correlates with the extent of service virtualization used. At the bottom of the test pyramid, we aggressively use both synthetic test data and virtual services. Towards the top of the pyramid, we use more realistic test data with real application components. We can use hybrid approaches for the middle tiers.
When using virtual services for test data, we need to make sure that we maintain consistency between data used to drive the tests, the application database, and the virtual service. The first two are typically taken care of by test data management (TDM) tools. For the virtual service, we need to either record or synthesize the virtual service with the same data set used for the test. (See figure 6 below.)
Figure 6: Synchronizing test data with virtual services
In order to achieve continuous SV, we need to ensure that the provisioning and deployment of virtual services are also automated along the CI/CD lifecycle. As discussed in the previous section, this is especially important in the CD part of the lifecycle, where we need to minimize elapsed time to reduce cycle time. This can be achieved by integrating the deployment of virtual services with deployment automation tools. For applications that are deployed in containers, we may package test assets (including virtual services) in side-car deployment containers and deploy them alongside application containers.
In this blog we have discussed what continuous SV is and its key practices. In the following blog, Continuous Service Virtualization, Part 2: Steps for Optimizing DevOps, we will discuss the continuous SV lifecycle and how it helps to optimize DevOps.