Environment inconvenients
The reliability of the automated tests must be one of the most important points to take into account when we decide to bring the automation to our project. In order to obtain a real result from our tests execution, it is essential that the environment where they are launched is as controlled as possible. An unstable environment can cause the number of false negatives to increase considerably and the bugs detected are not real issues in the application code. Therefore, our tests would no longer be reliable, the debugging process would be more expensive and they would lose their main function.
There are several factors for which we can consider that the test environment is not stable:
- There is no control over the database and there is no initial state or a reset after the modifications produced by the automatic tests.
- It is not exclusively dedicated to automated tests, so the data can be modified by developers or other profiles.
- There are uncontrolled deployments in the environment that can cause a temporary drop in services.
- There are dependencies with other external services not controlled by our product.
- The infrastructure is unstable in terms of resources and it produces spontaneous crashes.
If we detect any of the points described above, we should consider implementing the Wiremock solution.
Wiremock: Benefits and capabilities
Wiremock is an HTTP mock server, which works not only as a server that serves mock responses to a client app, but also works as a proxy in the communication between the client app and the API server, thus being able to record the requests and responses generated in the communication to generate mappings that will later serve as mocks for the application.
For this, Wiremock can be configured as a standalone element in the communication between the client app and the API or as a process that can be executed in an automated test using the Wiremock library itself. In both cases, Wiremock will stand as a receiving element waiting to receive calls to serve as mocks. When configured as a proxy, Wiremock will forward the request made by the app to the API, so that it returns the expected response, Wiremock will record the information received from the API with which it will generate a mapping. This mapping will help us to configure the mock in a much easier and simpler way.
Wiremock Setup
Standalone process
- Download the .JAR file from Wiremock website
- Start process with command in terminal
cd folder/with/wiremock_jar
java -jar wiremock-jre8-standalone-2.33.2.jar
Server will be accessible on http://localhost:8080__admin by default.
In-code execution
Implement Wiremock in Gradle and set up configuration:
implementation("com.github.tomakehurst:wiremock-jre8-standalone:2.33.2")
private val mainResourcePath = System.getProperty("user.dir") + "/src/test/resources"
private val wireMockServer = WireMockServer(options().port(8080).usingFilesUnderDirectory(mainResourcePath))
Start and stop the server with wiremockServer.start() and wiremockServer.stop()
Record mappings
To record all mappings on Wiremock you must enable proxy configuration, either if you run Wiremock as a standalone process or is being run through code.
Recommended to use as a standalone process.
java -jar wiremock-jre8-standalone-2.33.2.jar --proxy-all="URL" --record-mappings
There is also the possibility to run the wiremock as standalone without de proxy-all and record-mappings flags and configure the recording through the following URL:
http://localhost:8080/__admin/recorder/
Once Wiremock is up and running and endpoints are being called JSON files will be generated under a mappings folder with this similar structure (name can be formatted).
This file already contains the required information to create the mock stub, we can update the information as pleased.
{
"id" : "91555df1-f6de-44bc-a3c6-8cb6dab34728",
"name" : "v2_user_login",
"request" : {
"url" : "/v2/user/login?disableCaptcha",
"method" : "POST",
"bodyPatterns" : [ {
"equalToJson" : "{\"device_id\":\"${json-unit.any-string}\",\"device_model\":\"${json-unit.any-string}\",\"device_type\":\"phone\",\"email\":\"coa-qa+edat@login.com\",\"g-recaptcha-response\":\"test\",\"is_app\":true,\"os\":\"Android\",\"os_version\":\"${json-unit.any-string}\",\"password\":\"Test1313??\",\"version\":\"${json-unit.any-string}\"}",
"ignoreArrayOrder" : true,
"ignoreExtraElements" : true
} ]
},
"response" : {
"status" : 200,
"body" : "{\"data\":{\"type\":\"user_session\",\"attributes\":{\"language\":\"eng\",\"currency\":\"EUR\",\"id\":\"d0fbaf4f-65b7-4950-b883-6a2129f1fe42\"}}",
"headers" : {
"Date" : "Wed, 08 Jun 2022 09:32:21 GMT",
"Content-Type" : "application/json",
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Headers" : "origin, content-type, access-token, x-tracking-id, bp-client, If-None-Match, If-Match",
"Cache-Control" : "no-store, private",
"X-RateLimit-Limit" : "100",
"Strict-Transport-Security" : "max-age=31536000; includeSubDomains",
"X-Frame-Options" : "SAMEORIGIN",
"CF-Cache-Status" : "DYNAMIC",
"Expect-CT" : "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"",
"Server" : "cloudflare",
"CF-RAY" : "71809ea78a26958d-DUB"
}
},
"uuid" : "91555df1-f6de-44bc-a3c6-8cb6dab34728",
"persistent" : true,
"insertionIndex" : 42
}
Mocking the recorded mapping with email and response allows to create controlled flows in the app to test scenarios.
${json-unit.regex} allows us to include any string as valid to match with the expected request-response on the mapping.
Android
The only requirement is to make sure the app is connected to Wiremock server’s IP address and port (see BASE_URL ) in build.gradle file on app. Considering 192.168.0.18:8080 as the IP address and port of Wiremock that’s all that it’s needed for Wiremock to serve mocks to the app. In case Wiremock is working as a proxy in the communication, the tool should be set with this configuration –proxy-all=”URL_OF_API_SERVICE”.
iOS
Same as Android, we have to connect the app with the Wiremock server’s IP address and port (see APP_BASE_URL ) in the config file on the app. Considering 192.168.0.20:8080 as the IP
Conclusion
Faced with the problems of today’s companies in having dedicated environments for testing and that allow UI tests to be run consistently and isolated from the rest of factors outside the application code, the use of mocks for the execution of UI tests has proven to be a reliable solution. Wiremock allows us to record the communication between app and API to generate mappings that will finally work as stubs to serve the application the same answers for each scenario that is launched in the test, so that the results of each UI test will only depend on a single factor: the code.