Why microservices need macro testing

Flock Engineering
Flock Engineering Blog
4 min readJul 17, 2018

This is our first engineering blog. We hope to be posting our learnings on a regular basis through this portal. Feel free to post your comments below and stay tuned for more!

Question: What happens after we write a service on Flock?
Developer: We write the next service!
Right answer: We need to write tests.

Urgh. That dreadful word. Many engineers ask why we should test in the first place. After we agree that tests are necessary, the discussion goes:

Yew: Well…where do we start?
Mi: We should have done this earlier. Testing during development can-
Yew: Yeah yeah, I know. But what can we do now?!
Mi: We could use unit tests…

Unit tests are focused on a particular part of the system. This part is first isolated using mocks services, and tested by setting specific inputs into the module.

Let’s say we have a bot which moves on a board. It starts from the bottom left. We want it to go to the top right. You will find all the code for this here. One possible solution is:

The white arrows show moves.

Let’s say we write some unit tests for this bot, making sure that each move is correctly executed.

Green means sucess!

But wait…what happens if we change the path?

A change in the second move

That means….

Our tests break!

Hmm…let’s summarize our observations of unit tests:

Advantages:

  1. Complex logic is better tested as a set of units.
  2. They deal with a smaller section of the system, hence are good at isolating bugs.
  3. A specific scenario which is difficult to generate manually can be tested.
  4. They are easier to set up, as smaller parts have clear expectations. Also, mocking is simpler than correctly initializing objects.

Disadvantages:

  1. Unit tests break easily. Refactoring and code changes lead to a change in test expectations.
  2. We derive little context from looking at a single unit.
  3. Lots of tests need to be written to test the entire system. That means a lot of test code.
  4. Some situations which are impossible in business may be tested too. For example, let’s say a Person object queried from the DB is tested for negative age. The class persisting the Person object may have a check for this, making this test unnecessary.

Yew: “That’s a lot of disadvantages there! I think functional tests would be better. They focus on the business requirements of a system. That way, our implementation is no longer driving our tests.”

Functional tests are good for an end to end testing of functionalities. They treat the system as a black box. We assume that the correctness of an API can be determined by just testing it’s endpoints. All external services are hence stubbed.

The state of the machine can be checked using it’s exposed APIs

However, if there are errors within the black box, they may not propagate to the response. Unit tests perform better in that regard.

At Flock, we use various approaches for testing:

  1. Functional tests are widely used. All of our APIs are checked for various scenarios.
  2. Some modules with intense logic are tested using units.
  3. Any test failing will stop the code from building. It has to be fixed first.
  4. Our Quality Assurance team thoroughly tests the app. Both automated and manual testing tools are used here.
  5. After clearance, the code goes to production. In the first few crucial hours, it is monitored heavily.

That’s all we have for now! We will be back with another interesting topic soon. Feel free to post your comments below.

Cheers!

--

--