Mock your UI tests with Wiremock

Apiumhub - Aug 19 '22 - - Dev Community

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.

fMbZMq0P2X aNCjwQDoPHHNhVT80QsQcG7kE4dMxEjOU7ePNCg8Mtme9 j4ovU1xD D1wLGNiM9JJPIGI3bIWYaY YMrmspbx3PGXFr

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

  1. Download the .JAR file from Wiremock website
  2. Start process with command in terminal
cd folder/with/wiremock_jar
java -jar wiremock-jre8-standalone-2.33.2.jar
Enter fullscreen mode Exit fullscreen mode

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))
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

xD7xjzHDGM 8S0NZSIP6xbf9reOr1w8A9kuJZVkUoLycxQu93RPuOSD20gxGwhsdT3A42deTWzFWM z63kTAensqmYn9JDsATxgHTIo km4ufDamPDgbG2N6GU8vQrihfpspVP5YjeKp4btE3hWnA

{
  "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
}
Enter fullscreen mode Exit fullscreen mode

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”.

YTwwG2Wjl3A6tVGjKFEstXqMq91L09yLNodPaAXpHqbiFhPfG1IE0u QPaEmDiJuqrhitEAbDbMN3AiOVnmm7DPrqGzS8xukQJ xEg8yXH85SWbxNpqgUiukxItuPNn23blTg0N7r0

9PRsVC5Z75MWBxD i0CA98svuC9YhEr8F0UI MhnaI8jhKE5r3Mfwn hELgzcCDRhqzz3wjACqcwIRgPVunPIBH8isZiiO yANU8ksf2996Sp9YBTKLbcolS2HKMUdlpeLq60fl6ouL3qIS FSPsIA

29LQ64er3gWDVD4bELZq1NAu6utz0nqni0E2wbSS StKXVR3LkEbJMqpodDM3 9MvF7DFHiUiG n7rCK3OmNfLoqpqCilQo1iTT 8t60eHUWpTRVXeMs7R2SdQq5jHGfPJ0GOJaqymHiE6GN9Ft8jDs

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

s8dcBHeTBSbCUex9GXux 26qkk3bBfuDf1EuVuYPCCOeQOB9FAzWO0vu6gqzUaUHL0yQ1LtQFTyl26uEZC6o

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.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player