How to create acceptance tests for async micro services
Asked Answered
K

3

8

If I have Microservice, which should create User but since user creation is complex it uses queue, and user is actually created by the consumer the endpoint only takes request and returns ok or fail.

How do I create acceptance test for this acceptance criteria:
Given: User who wants to register
When: api is requested for user creation
Then: create user AND set hosting environment_id on new user

For this I have to wait while the environment is actually set up, which takes up to 30 seconds. And if I implement sleep inside my test, then I hit anti pattern wait and see how to properly test it without failing best practices?

Kostman answered 13/9, 2018 at 17:17 Comment(1)
Anyway it looks like this is more like integration test than acceptance testWhither
R
1

most proper might be, to return a response instantly, let's say "setup process started" (with a setup process id) and then have another API method, which will "obtain setup status" (for that setup process id) - and then proceed, when "setup has completed".

because, alike this nothing will be stuck for 30s, neither in tests nor production - and one could display a progress bar to the user, which indicates the current status, so that they will have an estimate how long it will take - whilst not getting the impression, that something is stuck or would not work.

one barely can test asynchronously, while the setup process by itself won't be asynchronous; and long-running tasks without any kind of status indicator are barely acceptable for delivery - because this only appears valid, while knowing what is going on in the background, but not whilst not knowing that.

whenever testing hits an anti-pattern, this is an indicator, that the solution might be sub-optimal.

Ranjiv answered 18/9, 2018 at 22:30 Comment(0)
S
1

I don't presume to tell you exactly how to code your acceptance tests without more detail regarding language or testing stack, but the simplest solution is to implement a dynamic wait that continuously polls the state of the system for a desired result before moving forward, breaking the loop (presuming you would use some form of loop, but that’s up to you) when the expected/desired response has been received.

This "polling" can take many forms such as:

a) querying for an expected update to a database (perhaps a value within a table is updated when the user is created)

b) pinging the dependent service until you receive the proper "signal" you are expecting to indicate user creation. For example, perhaps a GET request to another service (or another endpoint of the same service) returns a status of “created” for the given user, signifying that the user has been created.

Without further technical information I can’t give you exact instructions, but dynamic polling is the solution I use every day to test our asynchronous microservice architecture.

Keep in mind, this dynamic polling solution operates on the assumption that you have access to the service(s) and/or database(s) that contain the indicator for which you are "polling" when it is time to move forward with your test. Again, I'm the signal to move forward is something transparent such as a status change for the newly created user, the user's existence in a database/table either external or internal to the microservice, etc.

Some other assumptions in this scenario are:

a) sufficient non-functional performance of the System Under Test, where poor non-functional performance of the System Under Test would be a constraint.

b) a lack of resource constraints as resources are consumed somewhat heavily during the "polling", as resources are consumed somewhat heavily during the period of “polling”. (think Azure dynamic resource flexing, which can be costly over time).

Note: Be careful for infinite loops. You should insert some sort of constraint that exits the polling loop (and likely results in a failed test) after a reasonable period of time or number of attempts at your discretion.

Spielman answered 19/9, 2018 at 21:47 Comment(0)
U
0

Create a query service that given the user attributes (id, or name etc), will return the status of the user.

For the acceptance criteria, will be 2 part

  1. create-user service returns 200
  2. get-status service returns 200 (you can call it in a loop in your test).

This service will be helpful in the long run for various reasons

  1. Check how long is it taking to the async process to complete.
  2. At any time you can get status of any user, including to validate if a user is truly deleted / inactivated etc
  3. You can mock this service results in your end-to-end integrated testing.
Ultrasonic answered 21/9, 2018 at 0:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.