In today’s article, I will guide you through your Azure DevOps setup to perform automated load tests using k6. Before we begin, I want to take a minute to explain what load tests are and why they are essential.
What is a load test?
There are many different types of testing in software development. For example, some tests check that different model of an application work together as expected (integration testing), some focus on the business requirements of an application by verifying the output of action without considering the intermediate state (functional testing), and others perform different types of testing. Load testing is a type of performance testing as well as a type of stress test and capacity test. It focuses on verifying the application’s stability and reliability under both normal and peak load conditions.
Important
While load testing tests your application under realistic average or peak loads, stress testing tests it under conditions that far exceed realistic estimates.
How does load testing work?
During load testing, the testing tool simulates the concurrent requests to your application through multiple virtual users (VUs) and measures insights like response times, throughput rates, resource utilization levels, and more.
Why is load testing important?
In today’s world, both enterprises and consumers rely on digital applications for crucial functions. For this reason, even a small failure can be costly both in terms of reputation and money. For example, imagine if Amazon did not know the amount of traffic that its servers could sustain; it would fail to supply requests from its customer during peak seasons like Black Friday. You might think that this event is unlikely. However, according to a survey taken by the global research and advisory firm Gartner, in 2020, 25% of respondents reported the average hourly downtime cost of their application was between $301,000 and $400,000. Furthermore, 17% said it cost them $5M per hour.

What is k6?
k6 is an open-source load testing tool written in Go that embeds a JavaScript runtime to allow developers to write performance tests in JavaScript. Each script must have at least one default function. This function represents the entry point of the virtual user. The structure of each script has two main areas,
Init Code
Code outside the default function that is run only once per VU
VU Code
Code inside the default function that runs continuously as long as the test is running
// init code
export default function() {
// vu code
}
If you want to define characteristics like duration or DNS, or if you want to increase or decrease the number of VU during the test, you can use the options objects as follows,
export let options = {
test_1: {
executor: 'constant-arrival-rate',
rate: 90,
timeUnit: '1m',
duration: '5m',
preAllocatedVUs: 10,
tags: { test_type: 'api' },
env: { API_PROTOCOL: 'http' },
exec: 'api',
},
test_2: {
executor: 'ramping-arrival-rate',
stages: [
{ duration: '30s', target: 600 },
{ duration: '6m30s', target: 200 },
{ duration: '90s', target: 15 },
],
startTime: '90s',
startRate: 15,
timeUnit: '10s',
preAllocatedVUs: 50,
maxVUs: 1000,
tags: { test_type: 'api' },
env: { API_PROTOCOL: 'https' },
exec: 'api',
},
};
Azure DevOps and k6
Processes like continuous integration promote shift-left testing, giving you the advantage of discovering and addressing issues in the early stages of application development. However, you should run load tests designed to determine if your application can handle requests in an environment as close as possible to production. While the cost of maintaining an environment identical to that of production may be prohibitive, you should make it as similar as possible. If you have the resources, a solution might be to create a staging environment that is a copy of our production environment. Otherwise, you can consider carefully running tests on your production environment. In this demo, I will show you how to set up your DevOps to perform load testing of a .NET 5 API written in C# using k6. Now that you have a general understanding of this article’s leading players, let us dig into the demonstration.
Create the API
First, you need to create a new ASP.NET 5 API. You can do this easily by using the following code,
dotnet new sln
dotnet new webapi -o Training -f net5.0 --no-https
dotnet sln add Training/Training.csproj
To make this API more realistic, add the Entity Framework Core in-memory database provider and create a DbContext instance that represents a session with the database you will use to query and save instances of your entities.
public class ApplicationDbContext: DbContext {
public ApplicationDbContext(DbContextOptions < ApplicationDbContext > options): base(options) {}
public DbSet < Product > Products {
get;
set;
}
}
Then, register the context as a service in the IService Collection by copying and pasting the following instruction in your Startup.cs file,
services.AddDbContext<ApplicationDbContext>(opt => opt.UseInMemoryDatabase("ApplicationDbContext"));
Create the Product class with its attributes and methods,
public class Product {
public int Id {
get;
set;
}
public string Name {
get;
set;
}
public decimal Price {
get;
set;
}
public static void AddProduct(ApplicationDbContext context, Product product) {
context.Products.Add(product);
context.SaveChanges();
}
public static Product GetProductById(ApplicationDbContext context, int id) {
return context.Products.FirstOrDefault((p) => p.Id == id);
}
public static List < Product > GetAllProduct(ApplicationDbContext context) {
return context.Products.ToList();
}
public static void RemoveProductById(ApplicationDbContext context, int id) {
var productToRemove = context.Products.FirstOrDefault((p) => p.Id == id);
context.Products.Remove(productToRemove);
context.SaveChanges();
}
}
To complete your API, create a controller to define the methods of your API,
[ApiController]
[Route("[controller]")]
public class ProductController : ControllerBase
{
private readonly ApplicationDbContext _context;
public ProductController(ApplicationDbContext context)
{
_context = context;
}
[HttpPost]
[Route("AddProduct")]
public void AddProduct(Product product)
{
Product.AddProduct(_context, product);
}
[HttpPost]
[Route("RemoveProduct")]
public void RemoveProduct(int id)
{
Product.RemoveProductById(_context, id);
}
[HttpGet]
[Route("GetAllProducts")]
public IEnumerable<Product> GetAllProducts()
{
return Product.GetAllProduct(_context);
}
[HttpGet]
[Route("GetProduct")]
public Product GetProduct(int id)
{
return Product.GetProductById(_context, id);
}
}













Shubham SawantPosted Jul 20, 2022, 9:07 AM
Hi @Ivan Porta can you please give information on how we can do load testing using k6 with the asp.net MVC web application