Skip to content

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:

  1. Test Configuration: A/B tests and their variants are configured on a remote server.
  2. Loading Tests: The ABTestService automatically loads active test configurations from the server and stores them in the NgRx store.
  3. 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.
  4. Rendering: The <campus-ab-test> component or *campusAbTest directive is used in Angular templates to render the correct UI based on the user's assigned variant.
  5. Tracking: The ABTestService is 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.

typescript
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.

MethodDescriptionParametersReturns
getVariantAssignmentRetrieves 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: stringObservable<VariantType | null>
getAllVariantAssignmentsRetrieves 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[]>
trackEventTracks a generic user interaction event (e.g., a button click, form submission).testId: string, eventName: string, properties?: objectvoid
trackConversionTracks a conversion event, which is tied to a specific success metric of a test.testId: string, metricId: string, value?: numbervoid
trackImpressionTracks 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: VariantTypevoid
getActiveTestsRetrieves all currently active A/B tests from the store. Triggers a server fetch if the store is empty.-Observable<ABTestDefinition[]>
getTestByIdRetrieves the configuration for a single test by its ID from the store.testId: stringObservable<ABTestDefinition | null>
trackPageViewTracks a page view event as part of the user's journey through the application.page: stringvoid
getCurrentJourneyGets the user's current journey, including all page views and conversion events.-UserJourney | null
flushEventsForces 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.

html
<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 ​

InputTypeDefaultDescription
testIdstringundefinedRequired. The unique identifier for the A/B test.
trackImpressionsbooleantrueIf 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.

html
<!-- 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.

html
<!-- 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 ​

PropertyTypeDefaultDescription
campusAbTeststringundefinedRequired. The main directive expression, which is the test ID.
variantVariantTypeundefinedThe specific variant ('A', 'B', etc.) that this template corresponds to.
defaultbooleanfalseIf true, this template will be rendered as a fallback when no variant is assigned for the test.
trackImpressionsbooleantrueIf 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 *campusAbTest Directive 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.