or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdmatching.mdrecording.mdsanitization.mdtest-integration.mdtest-modes.mdtransforms.md
tile.json

test-integration.mddocs/

Test Framework Integration

Native integration with modern test frameworks, particularly Vitest, with support for test context extraction and session management for Azure SDK testing scenarios.

Capabilities

Test Context Types

Type definitions for integrating with test frameworks, providing the necessary context information for recording session management.

/**
 * Primary test context type alias for current framework support
 */
type TestInfo = VitestTestContext;

/**
 * Vitest-specific test context containing task information
 */
interface VitestTestContext {
  /** Current test task information */
  task: VitestTask;
}

/**
 * Vitest task interface extending base task functionality
 */
interface VitestTask extends VitestTaskBase {
  /** Test name */
  name: string;
  /** Optional parent test suite */
  suite?: VitestSuite;
}

/**
 * Vitest test suite interface for organizing tests
 */
interface VitestSuite extends VitestTaskBase {
  /** Suite name */
  name: string;
}

/**
 * Base interface for Vitest task/suite functionality
 */
interface VitestTaskBase {
  /** Task or suite name */
  name: string;
  /** Optional parent suite */
  suite?: VitestSuite;
}

Usage Examples:

import { describe, it, beforeEach, afterEach } from "vitest";
import { Recorder, TestInfo } from "@azure-tools/test-recorder";

describe("Azure Storage Tests", () => {
  let recorder: Recorder;

  beforeEach(async (testContext: TestInfo) => {
    // Create recorder with Vitest context
    recorder = new Recorder(testContext);
    
    await recorder.start({
      envSetupForPlayback: {
        "AZURE_STORAGE_CONNECTION_STRING": "fake-connection-string"
      }
    });
  });

  afterEach(async () => {
    await recorder.stop();
  });

  it("should upload blob successfully", async (testContext: TestInfo) => {
    // Test implementation using recorder
    // testContext automatically provides Vitest task information
  });
});

Test Context Validation

Type guard function for validating test context objects and ensuring compatibility with the recorder.

/**
 * Type guard function to check if a test context is a valid Vitest context
 * @param test - The test context object to validate
 * @returns true if the context is a valid VitestTestContext
 */
function isVitestTestContext(test: unknown): test is VitestTestContext;

Usage Examples:

import { isVitestTestContext } from "@azure-tools/test-recorder";

function createRecorderForTest(testContext: unknown): Recorder {
  if (!isVitestTestContext(testContext)) {
    throw new Error("Invalid test context provided. Expected Vitest context.");
  }
  
  return new Recorder(testContext);
}

// Validate context before using
async function setupTestRecording(context: unknown) {
  if (isVitestTestContext(context)) {
    const recorder = new Recorder(context);
    await recorder.start({
      envSetupForPlayback: { /* ... */ }
    });
    return recorder;
  } else {
    throw new Error("Unsupported test framework context");
  }
}

Vitest Integration Patterns

Common patterns for integrating the recorder with Vitest test suites.

Basic Test Setup

import { describe, it, beforeEach, afterEach } from "vitest";
import { Recorder } from "@azure-tools/test-recorder";
import { BlobServiceClient } from "@azure/storage-blob";

describe("Blob Storage Operations", () => {
  let recorder: Recorder;
  let blobServiceClient: BlobServiceClient;

  beforeEach(async (testContext) => {
    recorder = new Recorder(testContext);
    
    await recorder.start({
      envSetupForPlayback: {
        "AZURE_STORAGE_CONNECTION_STRING": "DefaultEndpointsProtocol=https;AccountName=test;AccountKey=fake==;"
      }
    });

    // Configure client with recorder
    blobServiceClient = new BlobServiceClient(
      process.env.AZURE_STORAGE_CONNECTION_STRING!,
      recorder.configureClientOptions({})
    );
  });

  afterEach(async () => {
    await recorder.stop();
  });

  it("should create container", async () => {
    const containerName = recorder.variable("containerName", `test-${Date.now()}`);
    const containerClient = blobServiceClient.getContainerClient(containerName);
    
    await containerClient.create();
    const exists = await containerClient.exists();
    expect(exists).toBe(true);
  });
});

Nested Test Suites

describe("Azure Key Vault", () => {
  describe("Secret Operations", () => {
    let recorder: Recorder;
    let secretClient: SecretClient;

    beforeEach(async (testContext) => {
      // Test context includes full suite hierarchy
      recorder = new Recorder(testContext);
      
      await recorder.start({
        envSetupForPlayback: {
          "AZURE_KEYVAULT_URL": "https://fake-vault.vault.azure.net",
          "AZURE_CLIENT_ID": "fake-client-id"
        }
      });

      secretClient = new SecretClient(
        process.env.AZURE_KEYVAULT_URL!,
        credential,
        recorder.configureClientOptions({})
      );
    });

    afterEach(async () => {
      await recorder.stop();
    });

    it("should set secret", async () => {
      const secretName = recorder.variable("secretName", `test-secret-${Date.now()}`);
      await secretClient.setSecret(secretName, "secret-value");
    });
  });
});

Parameterized Tests

describe.each([
  { region: "eastus", tier: "standard" },
  { region: "westus", tier: "premium" }
])("Storage Tests - $region $tier", ({ region, tier }) => {
  let recorder: Recorder;

  beforeEach(async (testContext) => {
    recorder = new Recorder(testContext);
    
    await recorder.start({
      envSetupForPlayback: {
        [`AZURE_STORAGE_CONNECTION_STRING_${region.toUpperCase()}`]: `fake-connection-${region}`,
        "STORAGE_TIER": tier
      }
    });
  });

  afterEach(async () => {
    await recorder.stop();
  });

  it("should handle region-specific operations", async () => {
    // Test implementation
  });
});

Session File Path Generation

The recorder automatically generates session file paths based on the test context hierarchy, creating organized recordings.

Path Generation Logic:

// For a test structure like:
describe("Azure Storage Tests", () => {
  describe("Blob Operations", () => {
    it("should upload file", async (testContext) => {
      // Session file path generated as:
      // recordings/Azure_Storage_Tests_Blob_Operations/should_upload_file.json
    });
  });
});

Usage Examples:

import { describe, it } from "vitest";

// Simple test - generates path: recordings/Simple_Test/should_work.json
describe("Simple Test", () => {
  it("should work", async (testContext) => {
    const recorder = new Recorder(testContext);
    // Recording saved to organized path based on test structure
  });
});

// Nested test - generates path: recordings/Service_Tests_CRUD_Operations/should_create_resource.json
describe("Service Tests", () => {
  describe("CRUD Operations", () => {
    it("should create resource", async (testContext) => {
      const recorder = new Recorder(testContext);
      // Recording path includes full suite hierarchy
    });
  });
});

Error Handling

Common error scenarios and handling patterns when working with test framework integration.

describe("Error Handling Tests", () => {
  it("should handle invalid test context", async () => {
    // This will throw an error due to invalid context
    expect(() => {
      new Recorder(undefined);
    }).toThrow("Unable to determine the recording file path");
  });

  it("should handle missing task information", async (testContext) => {
    // Simulate corrupted context
    const invalidContext = { ...testContext, task: { name: "", suite: undefined } };
    
    expect(() => {
      new Recorder(invalidContext);
    }).toThrow("Unable to determine the recording file path. Unexpected empty Vitest context");
  });
});