Simulating Multiple Users in App Insights with Integration Tests

Introduction

Application Insights is an application performance management service that allows you to monitor your live web application. It provides a real-time dashboard for monitoring your application's performance and usage. You can use Application Insights to track the performance of your web application, monitor user behavior, and diagnose issues. It also provides powerful analytics tools that allow you to analyze user behavior and identify areas for improvement.

Application Insights

Application Insights identifies users based on a unique user ID that is automatically generated and assigned to each user. This ID is stored in a cookie on the user's browser. When a user interacts with the application, Application Insights tracks these interactions using this unique ID, allowing it to monitor user behavior and performance. In case of monitoring applications without a user interface, you can create a custom telemetry initializer that populates the anonymous user ID with a unique identifier for each request.

When you are running integration tests for your web application, you may want to simulate multiple users sending telemetry data to Application Insights. This allows you to test how your monitoring setup such as, user cohorts, funnels, and other analytics tools behave when multiple users interact with your application. However, when running integration tests, the user ID might remain the same for all requests since they all originate from the same test environment. This can lead to inaccurate results when analyzing user behavior and performance.

In this article, you will learn how to simulate multiple users in Application Insights when running integration tests for your web application.

Prerequisites

To complete this tutorial, you will need:

  • An Azure subscription. If you don't have an Azure subscription, create a free account before you begin.
  • An Application Insights resource. If you don't have an Application Insights resource, create one by following the instructions in Create an Application Insights resource.
  • Visual Studio Code or any other code editor.

Application Setup

Create a new ASP.NET Core minimal API project and configure Application Insights. If you are unfamiliar with the setup process, refer to the "Application Insights for ASP.NET Core applications guide" guide to help you set up Application Insights in your project.

Write the following code in your Program.cs file that exposes an endpoint to send a custom event to denote a user viewing a product:

using Microsoft.ApplicationInsights;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddApplicationInsightsTelemetry();

// Build the ASP.NET Core web application.
var app = builder.Build();

app.MapGet("/{id}", (int id, TelemetryClient telemetry) => telemetry.TrackEvent("ViewProduct", new Dictionary<string, string> { { "id", id.ToString() }}));

// Run the application.
app.Run();

You can learn more about sending custom events to Application Insights in the "Sending Custom Events to Application Insights" documentation guide.

Writing Integration Tests

Create a new xUnit test project and add Microsoft.AspNetCore.Mvc.Testing and FluentAssertions NuGet packages to your test project. Create a class named CustomTelemetryInitializer that inherits from TelemetryInitializerBase and overrides the OnInitializeTelemetry method to set the user ID for telemetry data. This class will be used to set a custom user ID for each request sent to Application Insights.

using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.AspNetCore.Http;

namespace TestProject1;

public class CustomTelemetryInitializer(IHttpContextAccessor httpContextAccessor) : TelemetryInitializerBase(
    httpContextAccessor)
{
    private string _aiUserId = string.Empty;

    public void SetUserId(string userId)
    {
        _aiUserId = userId;
    }

    protected override void OnInitializeTelemetry(
        HttpContext platformContext,
        RequestTelemetry requestTelemetry,
        ITelemetry telemetry)
    {
        telemetry.Context.User.Id = _aiUserId;
    }
}

The CustomTelemetryInitializer inherits from TelemetryInitializerBase class that enables you to modify the telemetry data before it is sent to Application Insights. You can use the OnInitializeTelemetry method to enrich the telemetry data with custom properties. In this case, you will set a custom user identifier for each request. Application Insights will use this user identifier instead of its default user ID to track user behavior.

You will now use this class in your integration tests. Populate your test class with the following code that sets the CustomTelemetryInitializer as a pre-processor of telemetry data and sends a request to the application endpoint that you created earlier:

using System.Net;
using FluentAssertions;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;

namespace TestProject1;

public class UnitTest1
{
    [Theory]
    [InlineData("test-user-1")]
    [InlineData("test-user-2")]
    [InlineData("test-user-3")]
    public async Task SimulateUserInTests(string userId)
    {
        // Arrange
        var factory = new WebApplicationFactory<Program>().WithWebHostBuilder(builder =>
            builder.ConfigureServices(serviceCollection =>
            {
                serviceCollection.AddSingleton<ITelemetryInitializer, CustomTelemetryInitializer>();
            }));
        var telemetryInitializer =
            factory.Services.GetRequiredService<ITelemetryInitializer>() as CustomTelemetryInitializer;
        telemetryInitializer?.SetUserId(userId);
        var client = factory.CreateClient();
        var telemetryClient = factory.Services.GetRequiredService<TelemetryClient>();

        // Act
        var response = await client.GetAsync("/1");
        await telemetryClient.FlushAsync(CancellationToken.None);

        // Assert
        response.StatusCode.Should().Be(HttpStatusCode.OK);
    }
}

You can now run the tests and observe the telemetry data in Application Insights. To view the user count recorded in Application Insights, navigate to the Application Insights resource in the Azure portal and then click on the "Users" option in the "Usage" section. The following screenshot shows the user count recorded in Application Insights from my tests:

Users data

As shown in the screenshot, you can filter the user count by events such as ViewProduct that you configured in your API endpoint.

Conclusion

In this article, you learned how to simulate multiple users in Application Insights when running integration tests for your web application. You created a custom telemetry initializer to set a custom user ID for each request sent to Application Insights. You then used this custom telemetry initializer in your integration tests to simulate multiple users sending telemetry data to Application Insights. This allowed you to test how your monitoring setups, such as user cohorts, funnels, and other analytics tools, behave when multiple users interact with your application.


Similar Articles