A/B Testing β
This document provides a comprehensive guide for developers on how to use the A/B testing features available in this application. It covers the main ABTestService, the <campus-ab-test> component, and the *campusAbTest structural directive.
Overall Workflow β
The A/B testing module allows you to show different versions of a feature to different users and track the impact on user behavior.
The typical workflow is as follows:
- Test Configuration: A/B tests and their variants are configured on a remote server.
- Loading Tests: The
ABTestServiceautomatically loads active test configurations from the server and stores them in the NgRx store. - Variant Assignment: When a user encounters a feature that is part of an A/B test, the service assigns them a variant (e.g., 'A' for control, 'B' for the new version). This assignment is persisted to ensure the user sees the same variant on subsequent visits.
- Rendering: The
<campus-ab-test>component or*campusAbTestdirective is used in Angular templates to render the correct UI based on the user's assigned variant. - Tracking: The
ABTestServiceis used to track user interactions (trackEvent), conversions (trackConversion), and variant impressions (trackImpression). These events are batched and sent to the analytics backend.
ABTestService β
The ABTestService is the core of the A/B testing framework. It acts as the primary entry point for all A/B testing logic, including variant assignment, event tracking, and state management integration with NgRx.
How to Use β
Inject the service into your components, directives, or other services as needed.
import { Component, OnInit } from '@angular/core';
import { ABTestService } from '@campus/ab-test';
@Component({
// ...
})
export class MyFeatureComponent implements OnInit {
constructor(private abTestService: ABTestService) {}
ngOnInit() {
// Example: Get the assigned variant for a test
this.abTestService.getVariantAssignment('homepage-cta-test').subscribe((variant) => {
console.log(`User is in variant: ${variant}`);
});
}
onButtonClick() {
// Example: Track a custom interaction event
this.abTestService.trackEvent('homepage-cta-test', 'cta-clicked');
}
}Public Methods β
Here is a detailed breakdown of the public methods available on ABTestService.
| Method | Description | Parameters | Returns |
|---|---|---|---|
getVariantAssignment | Retrieves the assigned variant for a specific test and user. If the user is not eligible or an error occurs, it returns a fallback variant. | testId: string | Observable<VariantType | null> |
getAllVariantAssignments | Retrieves all variant assignments for the current user from the local store. If the store is empty, it triggers a fetch from the server. | - | Observable<VariantAssignment[]> |
trackEvent | Tracks a generic user interaction event (e.g., a button click, form submission). | testId: string, eventName: string, properties?: object | void |
trackConversion | Tracks a conversion event, which is tied to a specific success metric of a test. | testId: string, metricId: string, value?: number | void |
trackImpression | Tracks an impression event, signifying that a user has been exposed to a specific test variant. This is often handled automatically by the component/directive. | testId: string, variantId: VariantType | void |
getActiveTests | Retrieves all currently active A/B tests from the store. Triggers a server fetch if the store is empty. | - | Observable<ABTestDefinition[]> |
getTestById | Retrieves the configuration for a single test by its ID from the store. | testId: string | Observable<ABTestDefinition | null> |
trackPageView | Tracks a page view event as part of the user's journey through the application. | page: string | void |
getCurrentJourney | Gets the user's current journey, including all page views and conversion events. | - | UserJourney | null |
flushEvents | Forces the EventBatcherService to immediately send all queued analytics events to the backend. | - | void |
<campus-ab-test> Component β
The <campus-ab-test> component is a wrapper that conditionally displays one of its content-projected children based on the assigned A/B test variant. It's useful when you have multiple, distinct templates for your variants that you want to manage in one place.
How to Use β
Wrap the different versions of your UI inside the <campus-ab-test> component. Use the variant attribute on your child elements to specify which variant they correspond to.
<campus-ab-test testId="homepage-hero-test">
<!-- Variant A (Control Group) -->
<div variant="A">
<h1>Welcome to Our Standard Homepage</h1>
</div>
<!-- Variant B (New Design) -->
<div variant="B">
<h1>Experience Our New, Modern Homepage!</h1>
</div>
<!--
Fallback Content (Optional)
This content is rendered if no variant matches or if the test fails to load.
It is any content that does NOT have a `variant` attribute.
-->
<div>
<h1>Welcome to Our Homepage</h1>
</div>
</campus-ab-test>Inputs β
| Input | Type | Default | Description |
|---|---|---|---|
testId | string | undefined | Required. The unique identifier for the A/B test. |
trackImpressions | boolean | true | If true, the component automatically tracks a variant_shown impression event when a specific variant's content is displayed. |
*campusAbTest Directive β
The *campusAbTest is a structural directive that provides a more concise, inline way to conditionally render a single element based on an A/B test variant. It's ideal for smaller changes or when variants are scattered throughout a template.
How to Use β
The directive uses Angular's microsyntax to define the test ID and the conditions for rendering.
Showing a Specific Variant β
To render an element only for users assigned to a specific variant, provide the test ID as the main expression and the variant ID to the variant key.
<!-- This div will only be rendered if the assigned variant for 'promo-banner-test' is 'B' -->
<div *campusAbTest="'promo-banner-test'; variant: 'B'">
<h2>Special Offer! Get 20% Off Today!</h2>
</div>
<!-- This div is for users in the control group ('A') -->
<div *campusAbTest="'promo-banner-test'; variant: 'A'">
<h2>Welcome to Our Site</h2>
</div>Showing a Fallback/Default View β
To render a fallback element for users who are not assigned any variant (or in case of an error), use the default key.
<!-- This div will be rendered if no variant is assigned for the test -->
<div *campusAbTest="'promo-banner-test'; default: true">
<h2>Our Standard Banner</h2>
</div>Microsyntax Inputs β
| Property | Type | Default | Description |
|---|---|---|---|
campusAbTest | string | undefined | Required. The main directive expression, which is the test ID. |
variant | VariantType | undefined | The specific variant ('A', 'B', etc.) that this template corresponds to. |
default | boolean | false | If true, this template will be rendered as a fallback when no variant is assigned for the test. |
trackImpressions | boolean | true | If true, automatically tracks an impression event when the template is rendered for a specific variant. |
Component vs. Directive β
Use the
<campus-ab-test>Component when:- You have multiple, complex UI structures for each variant.
- You want to group all variants for a single test cleanly in one location in your template.
- You need a clear fallback block for the default case.
Use the
*campusAbTestDirective when:- You are making small, simple changes, like showing/hiding a single element.
- The UI changes for your variants are located in different parts of your template.
- You prefer a more concise, inline syntax.