Testing Event-Driven Microservices using C# .NET 🧪⚡️
Regardless of the system we build it has to be tested properly. It can be a large-scale system or a smaller system, testing has to be done in appropriate and efficiently way, which should be cost effective and takes less overhead to maintain in longer run.
The above statement is the guideline of this article discussion while testing Microservices.
Classical System
Before we start discussing about testing Event-Driven Microservices, let's quickly talk about a classical system and how it can be tested
As you can see, the above system is an 3-tier architecture based application, which has an UI, API and DB.
In order to test the classical system represented about we need to verify the UI, DB and API (as shown in the checkpoints above)
There are many tools available in the market to test UI, Database and API like
- UI — Playwright, Selenium, Cypress and many more
- API — RestSharp, Postman, RestAssured
- DB — via code or entity models
Event-Driven System
Now testing an Event-Driven system has bit more added complexity compared to the classical system. For instance an Event-Driven System architecture shown below
Will need testing of not just UI, API and DB, but also additional Publishers and Subscribers happening in Message Broker.
As you can see from the above architecture diagram, the system involves
- UI
- API Service
- Database
- RabbitMq
Both the CustomerService and InventoryService communicates with each other using rabbitMq Message broker defined in the topic exchange.
Testing an Event-Driven System
In order to test an event-driven system or any software system of that matter, we can take the guiding principle of Testing pyramid defined by Martin fowler as its applicable very much for larger system built with Microservices
We all know most of the testing should happen in the bottom three bars of the pyramid rather from top two. There are many supporting tools available while testing in .NET, but some of them I have mentioned with the logos in the above diagram.
Types of Testing with their Pros and Cons
UI Testing 🎭
Pros
UI testing using modern tools like Playwright, Cypress or Selenium is absolute breeze
- It can test the entire application flow once deployed
- Pretty much mimicking like end user behavior
- Find issue in UI functionality quickly
Cons
Like every positive side, there are also negative side effects comes along with it
- UI testing starts becoming fragile if application keeps changing (even single locator) 🤞
- Cause of effect of application change will not be known until the application is fully deployed 🤷♂️
- Entire application stack should be up and running all time like API, DB, UI and all the services 💰
- Very costly, considering application running all time in Cloud 🥲
- UI testing is known for its slow execution 🐌
API Testing
Pros
API testing using modern tools like Playwright, RestSharp is absolute breeze
- It can test the entire application flow once deployed
- Easy to call the API to perform CRUD operation
Cons
- Entire application stack should be up and running all time, pretty much like UI testing case above 💰
- Testing API should not be one sided, since change in API definition is only going to affect the consumer side rather producer side.
- Very costly, considering application running all time in Cloud 🥲
Integration Testing
Pros
Integration tests ensure that an app’s components function correctly at a level that includes the app’s supporting infrastructure, such as the
- Database,
- File system,
- Network
- Request-response pipeline
The main advantage of Integration testing is that, it can be done between every component rather the whole application infrastructure available at any given time, meaning, only targeted services and its dependencies needs to be present while testing the component.
With this above advantage we can see all the cons that we have with UI and API will go away in-terms of
- Cost 💰
- Fragile tests 💥
- Time to execute the tests 💨
How perform effective Integration tests in C#.NET?
Infrastructure components, such as the test web host and in-memory test server (TestServer), are provided or managed by the Microsoft.AspNetCore.Mvc.Testing
E.g code to spawn an service In-memory to test the application
public class TestFixtureBaseForInventory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
base.ConfigureWebHost(builder);
builder.ConfigureTestServices(services =>
{
var descriptor =
services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<ProductDbContext>));
if(descriptor is not null)
services.Remove(descriptor);
services.AddDbContext<ProductDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryInventoryDb");
});
var sp = services.BuildServiceProvider();
using var scope = sp.CreateScope();
using var appContext = scope.ServiceProvider.GetRequiredService<ProductDbContext>();
appContext.Database.EnsureDeleted();
appContext.Database.EnsureCreated();
});
}
public override async ValueTask DisposeAsync()
{
await Task.Run(() =>
{
Task.Delay(2500);
base.DisposeAsync();
});
}
}
As you can see from the above code, we are spinning up an InventoryService In-memory by creating the context ProductDbContext
Contract Testing
For Contract testing, we can use tool like Pact, which does help acheive contract testing much efficiently.
Pact is a consumer-driven contract testing tool, which is a fancy way of saying that the API Consumer writes a test to set out its assumptions and needs of its API Provider(s).
By unit testing our API client with Pact, it will produce a contract that we can share to our Provider to confirm these assumptions and prevent breaking changes.
Complete Course and more details
This whole article is part of my course in Udemy, where I have covered even more details related to all the testing approaches that we have discussed about in this article
Course in Udemy
If you think this course is something for you and wanted to enrol, do send out an email to karthik@techgeek.co.in or comment below, will send you the latest coupon code of discount.
Here is the launch coupon code which will valid till 29th of next year Jan 2022 EA_LAUNCH_23