Test Your Microservices with Skyramp in IntelliJ IDEA
Published: 2023-09-08 19:42:10

Hello devs! This is Dan from [Skyramp](https://www.skyramp.dev). When we say Skyramp meets devs in any workflow, we mean it. In this blog, we will demonstrate iterative testing and development for microservices in a local Kubernetes cluster performed directly from the IntelliJ IDEA with Skyramp. It’s as easy as 1, 2, 3.

## What Are We Testing?
This blog features the [Skyramp fork](https://github.com/letsramp/sample-microservices) of Google’s popular cloud-native microservices demo app, [Online Boutique](https://github.com/GoogleCloudPlatform/microservices-demo). Online Boutique is a web-based e-commerce app containing microservices that mimic real-world services, such as a product catalog, shopping cart, ad service, recommendation service, payment service, and others. The services use gRPC APIs by default, but Skyramp has also added support for REST and Thrift APIs.

This walkthrough will focus on the ad service component of the system to demonstrate how you can easily generate test descriptions and run tests during the development stage using Skyramp. The ad service is a microservice written in Java, so [IntelliJ IDEA](https://www.jetbrains.com/idea/) is a perfect fit for our development environment.

## Pre-Flight Checklist
Here’s what you need in order to follow along with this walkthrough:
- Install [Docker](https://www.docker.com/get-started/)
- Install the [Skyramp Terminal Client](https://www.skyramp.dev/docs/get-started/install-client/)
- Install [JetBrains IntelliJ IDEA](https://www.jetbrains.com/idea/) and [download a JDK](https://www.jetbrains.com/idea/guide/tips/download-jdk/)
- Clone the Skyramp project, `sample-microservices`, to a folder of your choice. From a terminal, run:
```
git clone https://github.com/letsramp/sample-microservices.git
```
## Let’s Get Testing
First, start the IntelliJ IDEA you installed and open the Skyramp `sample-microservices` project from the local folder where it was cloned. Navigate to the `src/adservice/src/main/java/hipstershop` folder and open the `AdService.java` file to view the ad service source code.

Next, open the Terminal pane in the IDE by clicking the Terminal button in the lower left corner. You can run all the skyramp commands from this Terminal. Change to the Skyramp demo directory for gRPC in the terminal and check your installed version of skyramp:
```
cd skyramp/grpc-demo
skyramp version
```
At this point, you should see something like this:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kborfnfdbjix0jqwk0d0.png)
Next, we will create a local Kubernetes cluster for deploying and testing the microservices. This is easily done with the Skyramp client:
```
skyramp cluster create --local
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92k17qirh7wrstd54poj.png)
Deploy all the services to the cluster that will make up our system under test using [Skyramp Deployer](https://www.skyramp.dev/docs/deployer):
```
skyramp deployer up grpc-app
```
Once the services are deployed, you can check the status of the services, also with Skyramp Deployer:
```
skyramp deployer status
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0pn1nm7d5yp7roas74c.png)
Now we will generate a test description for the ad service using [Skyramp Tester](https://www.skyramp.dev/docs/tester/). This will allow us to execute tests against the running service.
```
skyramp tester generate --protocol protobuf \
--api-schema pb/demo.proto --alias ad-service \
--port 9555 --proto-service AdService
```
How do you know what values to provide to Skyramp Tester in order to generate a test description? In this case, we know we will be using `protobuf` as the `protocol` for our distributed application. We already have a proto file defined in the repo at `pb/demo.proto`, so we can utilize that for the `api-schema` flag. The `AdService` is specified in the proto file, which is the service we want to test, so that should be used for the `proto-service` flag. The values for the `alias` and `port` flags are derived from the deployment status as seen in the screenshot above.

Once you run the Skyramp Tester command above, the generated test description file will be under the `tests` folder called `ad-service.yaml`. Next, we simply need to define our specific scenario for testing.

The ad service behavior we want to test is whether the service returns exactly two ads from its response payload, and if those ads are non-zero length. Furthermore, we want to test that the two ads are not the same, because we do not want duplicate ads returned. We can define all of this by adding a `scenarios` section with `asserts` in the file as seen below:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgw08r8qxfyuk6sx4ppk.png)
Here is the `scenario` section with the `asserts` to add to the YAML file if you would like to copy and paste:
```yaml
scenarios:
 - name: scenario1
   steps:
     - request: EAdServiceMGetAds
     - asserts: requests.EAdServiceMGetAds.res.ads.length == 2
     - asserts: requests.EAdServiceMGetAds.res.ads[0].text.length >= 1
     - asserts: requests.EAdServiceMGetAds.res.ads[1].text.length >= 1
     - asserts: requests.EAdServiceMGetAds.res.ads[0].text != requests.EAdServiceMGetAds.res.ads[1].text
```
Now save the file. Running the test is easy with Skyramp Tester. From the same `skyramp/grpc-demo` directory, just execute: 
```
skyramp tester start ad-service -n test-grpc-demo
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6myprsfaxd51uhefqziq.png)
Notice from the test results that the first three asserts passed, but the last assert failed. We appear to be getting duplicate ads from our ad service. A side note: this failed test may take several tries to surface, since the ads returned are randomized and may not always be the same. 

If we navigate back to the source file and examine the code, we see that `getRandomAds()` does not account for duplicates.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z98n2n5tz69jlejuc5ru.png)
We can fix that with a `LinkedHashSet` to force uniqueness. Here is the new `getRandomAds()` source with a few lines changed:
```java
private List<Ad> getRandomAds() {
  List<Ad> ads = new ArrayList<>(MAX_ADS_TO_SERVE);
  Collection<Ad> allAds = adsMap.values();
  Set<Ad>set = new LinkedHashSet<Ad>();
  while (set.size() < MAX_ADS_TO_SERVE) {
    set.add(Iterables.get(allAds, random.nextInt(allAds.size())));
  }
  ads.addAll(set);
  return ads;
}
```
We update the code in the editor and then rebuild the ad service from `src/adservice` in a new terminal pane by running:
```
cd src/adservice
./gradlew installDist
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j048ui8d4j2t6tkd65t6.png)
Once the ad service is rebuilt, simply bring all the services down and back up again with Skyramp Deployer:
```
skyramp deployer down grpc-app
skyramp deployer up grpc-app
```
Now, when you re-run the test with Skyramp Tester, all asserts will pass because the ad service no longer produces duplicate ads in the payload.
```
skyramp tester start ad-service -n test-grpc-demo
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74tejnf9ua3qpjr33e7n.png)
Once you are finished with your test session, you can remove the test cluster completely with Skyramp:
```
skyramp deployer down grpc-app 
skyramp cluster remove --local
```
## Wrapping Up
And there you have it. You can use this setup to explore more capabilities Skyramp provides with [Mocker](https://www.skyramp.dev/docs/mocker), [Tester](https://www.skyramp.dev/docs/tester), and [Deployer](https://www.skyramp.dev/docs/deployer). We give you all the tools you need to mock, test, and deploy your own microservices from IntelliJ IDEA easily with Skyramp.

Happy testing!

Have questions or comments? [Join the Skyramp Community Discord](https://discord.com/invite/qBnEZM6JTb).