August 15, 2019

How to Use BlazeMeter Mock Services for Testing

Test Automation
Service Virtualization

In addition to the newly introduced UI Functional testing and 360° API Testing and Monitoring, Blazemeter now provides Mock Services functionality. This is a critical aspect for when the application or module you are developing and testing is dependent on the other services or systems regardless whether external or internal. Such dependencies could cause a lot of troubles during testing as it may not be easily available when you need them or they may have constraints like costs or limited control over data it returns – and all of that typically leads to unwanted trade-offs during the testing.

Mock Services removes these dependencies and also helps to control the behavior of the dependencies by simulating the service using the endpoint provisioned by you - and this moves your testing to the next level. You can read this blog post on the benefits and concepts behind Mock Services and Service Virtualization concept in general.

In this blog we'll focus on how to use Mock Services within the Blazemeter platform, including exploring key concepts and integrations with open source tools like CodeSV and Wiremock. As already mentioned, Mock Services are part of the new Blazemeter Continuous Testing platform, and you can find them under Mock Services tab in Blazemeter menu header.

Back to top

How to Create your first Mock Service

 

If you access Mock Services for the first time, you are routed to the “Learn more” section of Mock Services screen that gives you basic overview about the functionality and points you to various guides and help topics to explain the concept in detail. But besides that, it also provides a quick-start experience how to create your first Mock Service.

mock services in blazemeter main menu

It is as simple as taking an already existing Swagger specification, har file or .json exported from Wiremock or CodeSV and dropping this file inside the dropzone area on the top of the screen. After  a few seconds, your screen switches to the Mock Services administration and your first Mock Service is created and ready to be run.

In my example, I am using the “Sample transaction file” available via link placed just below the dropzone in the Learn More page – which is a .har file containing traffic from a hypothetical petstore.blazemeter.com application.

mock services setup

But before we run it, let’s investigate what happened behind the scenes and with what concepts we are working on.

As discussed before Mock Service behaves like the real service – simulates its responses and it is represented by endpoint you have under your control. Its behavior is driven by Transactions. A single Transaction defines the HTTP request-response structure where the request part represents the request matching and the response part defines the response that should be provided when request is matched – it is following the following semantics: “if the request received by Mock Service matches the conditions, then return defined response”.

Request matching could be defined by the exact match of the URL path, HTTP operation, by query parameters, request headers, request body, cookies or authentication. Various matching operators are available as well as ability to match request values by regular expressions (see Request Matching Examples for more details). The end goal is to return responses that appears exactly as being returned by the real service so you can use Mock Service instead of the real service during testing of your application.

When the file was dropped into the dropzone in Learn More page, request and response data were extracted and turned into the Transactions that were automatically added to the Mock Service created for you during the Learn More quick-start flow. You can check that by expanding the row of the newly created Mock Service in the table – there should be 5 different transactions assigned to your Mock Service. And these transactions will drive the behavior of the Mock Service.

mock services upload files

In this simple example, we can keep all pre-selected default values and just press “Run Mock Service”. After few seconds, Mock Service is provisioned for you in cloud and it is accessible via the endpoint. Let’s copy this endpoint to the browser and add /api/pets and press enter – congratulations, you have got your first response from your Mock Service!

setting up mocking in blazemeter

running mock services with blazemeter

It the next part, let’s take a look at an example which is much closer to real-life scenario..

 

Dealing with application dependencies

 

Let’s suppose I am developing and testing my Digital Bank web application. One of its features is the “ATM Search” that is being powered by the external 3rd party service responsible for ATM Search (synapsefi.com) – it searches for the ATMs within a radius of the area provided by zip code. My application just sends request to this 3rd party API, gets search results in response and displays them nicely in user interface. 

setting up mock services in blazemeter

mock services in blazemeter

blazemeter mock services

Note: This Digital Bank demo application is open-source and available for your experiments - feel free to check out its source code https://github.com/asburymr/Digital-Bank. You can follow this blog post and try all of the actions by yourself.

There are a couple of issues with this setup causing issues in testing:

  1. I cannot rely on the data returned from 3rd party service – what if the number of ATMs changes over time, but your test is designed according to particular number of ATMs?
  2. Service may not be available all the time.
  3. I have no control over which data it returns and how it behaves – I cannot reproduce certain cases at will or at all.
  4. There may be associated costs with using this service – which is something I would like to avoid during the testing.

This is a typical scenario when your application is dealing with any dependency – which may be 3rd party or just a service on which different sitting on the opposite side of the office is working on. The obvious answer to all of the issues mentioned above is – Let’s mock it!

Back to top

Import Transactions for dependency of your application

 

As we discussed in the beginning, Transactions are the objects that drive Mock Service. So let’s start with them. There are many ways how to create Transactions – by importing various type of files (Swagger, har, json definitions of Wiremock and CodeSV stubs) that capture or define the HTTP traffic or API specs or manually using the editor in Transactions tab within Mock Services. Let’s assume I have already captured the har file that represents sample traffic to the ATM search 3rd party service.

Let’s switch to the Transactions screen and drop the .har file in the dropzone area on top of the screen. The “Import Transactions” dialog opens – I have to pick a Service where my Transactions will be created. Service is an entity that represents the real service I want to mock and helps me to keep all assets relevant to the real service under single object – for now, we can treat is as a folder that keeps Transactions and Mock Services related to a particular real service under one parent. By typing a name of the Service, I can either search for the existing or create the new one – and I want to create “ATM Search” service.

blazemeter service virtualization

Also, all of the Transactions that will be created may be tagged – tags helps to organize transactions into more granular logical groups like for example “dev” for Transactions relevant to testing during the development, “regression” for stuff important for regression testing or “negative” for Transaction representing some negative behavior of the service. Let me choose tag “digital-bank” just to indicate that these ones are related to my Digital Bank application development and testing.

 

service virtualization with blazemeter

Once the import process finishes, I will get two Transactions created in my repository. First of all, I will deep-dive into them to understand more the logic inside.

mocking with blazmeter continuous testing platform

One of them represents the regular case – for the request using the given path and query parameter with zip code, it returns response with content of 2 ATMs. For convenience, let’s rename this Transaction to “OK Response”.

mock services with performance testing

blazemeter service virtualization

The other one is pretty similar, but returns no ATMs – it is still a valid response as it returns expected JSON structure, but simply there are no ATMs found. I may want to rename it to “Empty response” and also change the query parameter zip matching value “94204” so my Mock Service can provide one or the other response based on the specific query parameter value send in the request.

open source service virtualization with blazemeter

blazemeter open source service virtualization

These two Transactions are enough for my basic testing – I can test whether my application correctly renders a case where some ATMs are returned (and thanks to the Mock Service I know I can base my test assertions on the 2 ATMs being returned) and also I can test how does my application behave if there are no ATMs found – does it handle this edge case correctly? Mock will help me to figure that out. But I can do more – let’s clone the “Empty response” Transaction using the inline action in the table.

open source based mock services with blazemeter

how to set up blazemeter mock services

I will change the cloned Transaction to return some error response – let’s pick “410 - Gone”, delete the response body and for convenience rename this Transaction to “Error response” and assign tag “negative”. This way I have defined an error behavior and I am interested if my application can recover from such error returned from the dependent service (e.g. provide some user friendly message rather than fail with some ugly stack trace output displayed over my nicely designed UI). Remember, that I am not able to test such case with the real service as I have no way how to force it to behave like this at will – but with Mock Service, I have it under my control pretty easily.

how to run service virtualization with blazemeter

Back to top

From Transactions to running Mock Services

 

In total, I have three different transactions and I am ready to create Mock Service and use it for my testing. Let’s switch to Mock Services screen. Using the + button, I create new Mock Service – I can define name of the Mock Service, Service under which it belongs, location where it will be deployed (either cloud provisioned by Blazemeter or my OPL location if I need to access Mock Service endpoint behind firewall) and whether it is going to represent http or https host. When expanded, I can select which Transactions it should host – the left side represents Transactions available in my Service, right-hand side represents what is deployed (or going to be deployed) to the Mock Service endpoint. In this case I will move “OK response” and “Empty response” from left to right – my Mock Service will host these two Transactions.

 

blazemeter mock services

The “Parameters” section allows me to define what should happen if the request is not matched by Transactions inside the Mock Service – it can either return 404 or redirect to the real system (so I can selectively mock only what I defined, the rest of the traffic will be bypassed to the real system). I can also define “Think Time” which simulates additional delay in provisioning of the response. This is especially useful in software performance testing when I may want stable behavior of the application dependencies so the overall performance of my application is not affected by any network glitches or on the other hand I may be interested what it is going to happen if the dependent service providing responses in a very slow pace. But for now, I am fine with the defaults for both parameters.

blazemeter mocking

Now I am ready to press “Run Mock Service” to spin it up. After few seconds I will get Mock Service simulating the ATM Search service running in cloud. I can quickly copy the endpoint and just to experiment a bit paste it to browser and add the path and query parameter:

setting up mock services with blazemeter

Hitting https://atmsearchmock233-8080-default.mock.blazemeter.com/v3.1/nodes/atms?zip=94203 returns response with 2 ATMs. https://atmsearchmock233-8080-default.mock.blazemeter.com/v3.1/nodes/atms?zip=94204 on the other hand returns empty response with no ATMs https://atmsearchmock233-8080-default.mock.blazemeter.com/v3.1/nodes/atms?zip=94205 gives me 404 “No match found” as there is no matching Transaction...

mock services with code

Now, I can reconfigure my Digital Bank application to use the Mock Service endpoint instead of the real 3rd party service endpoint. (For those who follows this blog with hands-on trial, you can run Digital Bank Docker container with additional parameter that reconfigures application to point to a Mock Service – in my case: docker run -p 8080:8080 -e 'IO_DEMO_BANK_ATM_HOST=atmsearchmock233-8080-default.mock.blazemeter.com' asburymr/digitalbank). Let’s check what happens inside the application.

For zip code 94203 it correctly displayed two ATMs found; for 94204 correct message that no ATM has been found.

mock services with code

blazemeter mock services

Back to top

Playing with errors

 

Now, I can go back to Mock Services, expand my Mock Service in the table and check the log – it will give me an overview what requests have been sent to Mock and whether they were matched or not, which may help in debugging why a request is not matched.

blazemeter mocking

Additionally, I would like to change my Mock Service behavior to host the error response I created earlier. But before doing that I can take a snapshot of my current Mock Service and store it as a Mock Service Template so I can later easily recall this exact configuration – which is based on hosted Transactions and Parameters. I just provide convenient name like “ATM Search normal behavior” and save it.

creating mock services with blazemeter

creating service virtualization in blazemeter

Going back to my Mock Service, I can just swap “OK response” and “Empty response” Transactions with “Error response” – so my Mock will host only the error behavior now. By pressing “Update”, the Mock Service is being reconfigured according to the new settings.

SV and blazemeter

Once done, I can go back to my Digital Bank application which is still running and pointing to my Mock Service and try to search for ATM again. Now the results page shows error message indicating that something went wrong. This is acceptable for me, the search failed gracefully – no stack traces or cryptic errors are displayed.

creating mock services in blazemeter continuous testing platform

Again, for convenience I can go to Mock Service and create a template snapshot of this Mock Service configuration and call it “ATM Search negative behavior” – so I have two templates keeping different behavior of my Mock Service which allows to easily create new Mock Services based on these templates.

 

blazemeter mock services

Back to top

Introduction of Self-Defining Test Assets – tests that know what they need

 

Now, I would like to use all of what I prepared together with Blazemeter tests. Obviously, I can just wire my application to the Mock Service, configure my Mock Service according my needs and run tests, however Blazemeter can do some of that for free via a concept of Self-Defining Test Assets.

Let’s suppose that I have two tests – one test is supposed to test the normal behavior of the application. The second test scenario is intended to test unexpected or error cases that may happen in my application. As we already know, this is represented by different Transactions and also by different Mock Service Templates I have created for my Digital Bank scenario. In order to be able to run these two tests I would either need to define smart matching logic, so one Mock Service will contain all potential transactions and match them based on different test scenarios; or to define two

Mock Services where each service hosts different behavior for different test scenarios (but then I need to rewire my application before every test to a different Mock Service); or before every test to manually reconfigure my single Mock Service to host different Transactions. Self-defining test assets could to this for me automatically!

In my test configuration, I can use the new section called “Mock Services” to define what behavior my test expects from the Mock Service. By enabling this section and pressing +, I can add new Mock Service entry and define whether the selected Mock Service should be configured according “ATM Search normal behavior” or “ATM Search negative behavior” template. So for “Normal Behavior Test” I selected “ATM Search normal behavior” template and for “Unexpected Behavior Test” I chose “ATM Search error behavior”.

Once I wire my application to the Mock Service, I can then just execute these tests and each test during the pre-execution phase automatically reconfigures behavior of the associated Mock Service according to the provided template. I do not need to care which set of transactions or which template is relevant to various tests – test itself declares this dependency.

mock services with Taurus

Using my Taurus script I could go even into bigger granularity and besides using templates I can define associated Mock Service behavior by sequence of Transactions or by filtering by tags. Just add one of these definitions of dependencies to your Taurus files:

dependencies: services: - service: ATM Search mock-service: ATM Search Mock mock-service-template: ATM Search normal behavior dependencies: services: - service: ATM Search mock-service: ATM Search Mock transactions: - OK response - Empty response dependencies: services: - service: ATM Search mock-service: ATM Search Mock transaction-filter: tags: - negative

 

Back to top

What about creating Mock Services directly in code?

 

The last part of this introduction to Mock Services is focused primarily to developers and the way how developers could use mock services directly in the code (anything what could be described by code always makes developers happy) and collaborate with non-developers via Transactions repository.

Using libraries like CodeSV or Wiremock developers can define mock services-like functionality directly in the code and leverage the advantages of Mock Services during development phase and build robust integration test directly in the code - i.e. to create something like this example using CodeSV (Wiremock code looks very similar).

@Test

public void testSearchATMLocations() throws Exception {

forGet("https://uat-api.synapsefi.com:443/v3.1/nodes/atms")

.matchesQuery("zip", "94204")

.usingHttps(

withSecureProtocol("TLS")

.keystorePath(KEYSTORE_PATH)

.keystorePassword(KEYSTORE_PASSWORD)

.keyPassword(KEYSTORE_PASSWORD)

)

.doReturn(okMessage().withJsonBody(RESPONSE_EMPTY));

List results = searchService.searchATMLocations("94204");

assertTrue(results.isEmpty()); }

 

This way, developer can easily and naturally define mock services in the code and they are created behind the scenes within the code runtime. This is great for developers, but how to re-use the stuff they defined in the code in Blazemeter where additional team members can contribute and add new Transactions to simulate behaviors that developer did not cover initially?

It is easy, CodeSV 2.0 and our Wiremock extension provides a way to convert these in-code definitions into transactions and upload them to the Transaction Repository (directly from the code or via exported JSON file). This way, whatever developer created in the code is available out of the code scope in Transactions Repository so anybody can create Mock Service in Blazemeter based on these Transactions and associate this Mock Service with Blazemeter tests. In addition, any Transactions created in Transaction Repository (regardless of whether they were initially created from code or not) could be referred from code – so developers can use the stuff somebody else created and fine-tuned in the Transaction Repository.

This positions Mock Services as a uniquely flexible solution that connects different personas participating in software development and testing and benefits from Mock Services.

Developers can choose to use the streamlined and simple UI of Mock Services in Blazemeter or in-code approach using CodeSV or Wiremock, they can work together with testers who may leverage Mock Service intuitive UI as well as enrich their tests via Blazemeter UI or Taurus.

START TESTING NOW

Back to top