Guide for running tests in the openai-dotnet repository. Use this when asked to run, debug, or validate tests, or when writing new tests. Explains test modes (Playback, Record, Live), how to identify recorded vs non-recorded tests, environment variable configuration, and what to do when recordings are missing or stale.
npx skills add https://github.com/openai/openai-dotnet --skill running-tests
Tests in this repository use the Microsoft.ClientModel.TestFramework and NUnit.
Many tests rely on session recordings — pre-recorded HTTP interactions stored in tests/SessionRecords/ — so they can run without live service access. The repository defaults to Playback mode unless overridden in the environment.
| Mode | Description |
|------|-------------|
| Playback | Tests run against pre-recorded session data in tests/SessionRecords/. No API key is required. |
| Record | Tests run against the live OpenAI API and produce or update session recordings. Requires an API key. |
| Live | Tests run against the live OpenAI API without producing or updating session recordings. Requires an API key. |
The mode is controlled by the CLIENTMODEL_TEST_MODE environment variable and accepts Playback, Record, or Live.
In Playback mode, the framework may attempt to auto-record when a session recording is missing or stale. Disable that behavior by explicitly setting CLIENTMODEL_DISABLE_AUTO_RECORDING to true.
As the agent, only execute tests in Playback mode.
Do not run Record or Live mode yourself. Those paths require live credentials which you do not have.
Before running tests, always set:
$env:CLIENTMODEL_TEST_MODE = "Playback"
$env:CLIENTMODEL_DISABLE_AUTO_RECORDING = "true"
If a recorded test needs new recordings or updated recordings, you must follow the instructions below to ask a human to capture them for you instead of trying to capture them yourself.
Treat these as practical indicators instead of a rigid checklist.
OpenAIRecordedTestBase.[RecordedTest].GetProxiedOpenAIClient.OpenAIRecordedTestBase or has no base class.[Test] instead of [RecordedTest].MockPipelineTransport, MockPipelineResponse, or GetClientOptionsWithMockResponse.Recordings must be captured by a human.
Request recordings from a human before considering your work complete in either of the following cases:
When asking for recordings, always provide:
NUnit.Where expressiondotnet test commandYou must use this template:
> Please record tests using the recording workflow:
> https://github.com/openai/openai-dotnet/actions/workflows/record-test.yml
>
> Use the following NUnit.Where expression:
> `text
> test == 'Namespace.TestClass.TestMethodName'
> `
>
> Alternatively, run the following command locally and push the recordings manually:
> `powershell
> dotnet test ./tests/OpenAI.Tests.csproj --configuration Release --framework "net10.0" -- NUnit.Where="test == 'Namespace.TestClass.TestMethodName'"
> `
Use NUnit.Where for recording requests even when dotnet test --filter would work locally. NUnit.Where is the contract used by the recording workflow. Prefer test == ... because it matches the exact discovered NUnit test name and avoids ambiguity. For NUnit fixture-parameterized tests such as classes constructed with bool isAsync, the discovered test names may include fixture arguments like (True) or (False).
For a single ordinary test, use:
test == 'Namespace.TestClass.TestMethodName'
If you need one exact fixture instance, use:
test == 'Namespace.TestClass(True).TestMethodName'
Example for async fixture instance of the GenerateSingleEmbedding recorded test:
test == 'OpenAI.Tests.Embeddings.EmbeddingsTests(True).GenerateSingleEmbedding'
If multiple tests need recording, combine them in a single NUnit.Where expression:
(test == 'Namespace.TestClass.TestA') or (test == 'Namespace.TestClass.TestB')
Example for both fixture instances of the GenerateSingleEmbedding recorded test:
(test == 'OpenAI.Tests.Embeddings.EmbeddingsTests(True).GenerateSingleEmbedding') or (test == 'OpenAI.Tests.Embeddings.EmbeddingsTests(False).GenerateSingleEmbedding')
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Comprehensive GitHub release orchestration with AI swarm coordination for automated versioning, testing, deployment, and rollback management
Migrate test files from `as` type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace `as` in tests, or needs partial test data.
Modern JavaScript/TypeScript development with Bun runtime. Covers package management, bundling, testing, and migration from Node.js. Use when working with Bun, optimizing JS/TS development speed, or migrating from Node.js to Bun.
You are a dependency management expert specializing in safe, incremental upgrades of project dependencies. Plan and execute dependency updates with minimal risk, proper testing, and clear migration pa
Master systematic debugging techniques, profiling tools, and root cause analysis to efficiently track down bugs across any codebase or technology stack. Use when investigating bugs, performance issues, or unexpected behavior.
Opinionated backend development standards for Node.js + Express + TypeScript microservices. Covers layered architecture, BaseController pattern, dependency injection, Prisma repositories, Zod validation, unifiedConfig, Sentry error tracking, async safety, and testing discipline.
Best practices for writing JavaScript/TypeScript tests using Jest, including mocking strategies, test structure, and common patterns.
Take openai/running-tests from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.