Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8bdad4e
ignore failing tests
m-redding Sep 5, 2025
e717cca
move to nunit 4 patterns
m-redding Aug 15, 2025
3416acf
upgrade nunit
m-redding Aug 15, 2025
632549a
first set of tests moved to ClientTestBase (auto sync/async)
m-redding Sep 8, 2025
30f13c7
next set to ClientTestBase
m-redding Sep 8, 2025
16509f5
Merge branch 'main' into addtestframeworktake2
m-redding Sep 8, 2025
a044e6e
last few test files
m-redding Sep 9, 2025
5088ce1
Merge branch 'openai:main' into addtestframeworktake2
m-redding Sep 9, 2025
a0b2c35
move to dev feed version
m-redding Sep 9, 2025
d56bcb8
Merge branch 'openai:main' into addtestframeworktake2
m-redding Sep 12, 2025
74beb44
Merge branch 'addtestframeworktake2' of https://github.com/m-redding/…
m-redding Sep 12, 2025
c4e8c20
add batch/chat tests
m-redding Sep 16, 2025
08cf150
update
m-redding Sep 16, 2025
4325136
Merge branch 'openai:main' into addtestframeworktake2
m-redding Sep 16, 2025
30ea2d0
add chat tests
m-redding Sep 16, 2025
849cbde
add audio tests
m-redding Sep 16, 2025
db74b03
containers, assistants, responses
m-redding Sep 16, 2025
82379a2
models and moderations
m-redding Sep 16, 2025
a95f905
remaining tests
m-redding Sep 17, 2025
cbcd651
be more flexible in test environment
m-redding Sep 17, 2025
ab821f7
changes for pipeline
m-redding Sep 17, 2025
127459c
feedback
m-redding Sep 18, 2025
7442234
bump test proxy and test framework versions
m-redding Sep 22, 2025
a777478
update recordings
m-redding Sep 25, 2025
1f1109c
more recordings updates
m-redding Sep 25, 2025
1f27832
update more recordings
m-redding Sep 26, 2025
d5c5bd0
Merge branch 'main' into addtestframeworktake2
m-redding Sep 26, 2025
565db7d
merge conflicts and new recordings
m-redding Sep 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
"snippet-generator"
],
"rollForward": false
},
"azure.sdk.tools.testproxy": {
"version": "1.0.0-dev.20250805.1",
"commands": [
"test-proxy"
],
"rollForward": false
}
}
}
426 changes: 124 additions & 302 deletions tests/Assistants/Assistants.VectorStoresTests.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tests/Assistants/AssistantsSmokeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void ResponseFormatEquality()
Assert.That((AssistantResponseFormat)null != AssistantResponseFormat.CreateTextFormat());
Assert.That(AssistantResponseFormat.CreateTextFormat() != null);
Assert.That(AssistantResponseFormat.CreateTextFormat(), Is.Not.EqualTo(null));
Assert.That(null, Is.Not.EqualTo(AssistantResponseFormat.CreateTextFormat()));
Assert.That(AssistantResponseFormat.CreateTextFormat(), Is.Not.Null);

AssistantResponseFormat jsonSchemaFormat = AssistantResponseFormat.CreateJsonSchemaFormat(
name: "test_schema",
Expand Down
999 changes: 183 additions & 816 deletions tests/Assistants/AssistantsTests.cs

Large diffs are not rendered by default.

18 changes: 4 additions & 14 deletions tests/Audio/GenerateSpeechMockTests.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
using System;
using System.ClientModel;
using System.Threading;
using Microsoft.ClientModel.TestFramework;
using NUnit.Framework;
using OpenAI.Audio;
using OpenAI.Tests.Utility;

namespace OpenAI.Tests.Audio;

[TestFixture(true)]
[TestFixture(false)]
[Parallelizable(ParallelScope.All)]
[Category("Audio")]
[Category("Smoke")]
internal class GenerateSpeechMockTests : SyncAsyncTestBase
internal class GenerateSpeechMockTests : ClientTestBase
{
private static readonly ApiKeyCredential s_fakeCredential = new ApiKeyCredential("key");

Expand All @@ -24,19 +22,11 @@ public GenerateSpeechMockTests(bool isAsync)
[Test]
public void GenerateSpeechRespectsTheCancellationToken()
{
AudioClient client = new AudioClient("model", s_fakeCredential);
AudioClient client = CreateProxyFromClient(new AudioClient("model", s_fakeCredential));
using CancellationTokenSource cancellationSource = new();
cancellationSource.Cancel();

if (IsAsync)
{
Assert.That(async () => await client.GenerateSpeechAsync("text", GeneratedSpeechVoice.Echo, cancellationToken: cancellationSource.Token),
Assert.That(async () => await client.GenerateSpeechAsync("text", GeneratedSpeechVoice.Echo, cancellationToken: cancellationSource.Token),
Throws.InstanceOf<OperationCanceledException>());
}
else
{
Assert.That(() => client.GenerateSpeech("text", GeneratedSpeechVoice.Echo, cancellationToken: cancellationSource.Token),
Throws.InstanceOf<OperationCanceledException>());
}
}
}
33 changes: 15 additions & 18 deletions tests/Audio/GenerateSpeechTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using NUnit.Framework;
using Microsoft.ClientModel.TestFramework;
using NUnit.Framework;
using OpenAI.Audio;
using OpenAI.Tests.Utility;
using System;
Expand All @@ -8,11 +9,8 @@

namespace OpenAI.Tests.Audio;

[TestFixture(true)]
[TestFixture(false)]
[Parallelizable(ParallelScope.All)]
[Category("Audio")]
public partial class GenerateSpeechTests : SyncAsyncTestBase
public partial class GenerateSpeechTests : OpenAIRecordedTestBase
{
public GenerateSpeechTests(bool isAsync) : base(isAsync)
{
Expand All @@ -21,14 +19,15 @@ public GenerateSpeechTests(bool isAsync) : base(isAsync)
[Test]
public async Task BasicTextToSpeechWorks()
{
AudioClient client = GetTestClient<AudioClient>(TestScenario.Audio_TTS);
using (Recording.DisableRequestBodyRecording()) // Temp while multipart support in the test proxy is being implemented
{
AudioClient client = GetProxiedOpenAIClient<AudioClient>(TestScenario.Audio_TTS);

BinaryData audio = IsAsync
? await client.GenerateSpeechAsync("Hello, world! This is a test.", GeneratedSpeechVoice.Shimmer)
: client.GenerateSpeech("Hello, world! This is a test.", GeneratedSpeechVoice.Shimmer);
BinaryData audio = await client.GenerateSpeechAsync("Hello, world! This is a test.", GeneratedSpeechVoice.Shimmer);

Assert.That(audio, Is.Not.Null);
ValidateGeneratedAudio(audio, "hello");
Assert.That(audio, Is.Not.Null);
await ValidateGeneratedAudio(audio, "hello");
}
}

[Test]
Expand All @@ -41,7 +40,7 @@ public async Task BasicTextToSpeechWorks()
[TestCase("pcm")]
public async Task OutputFormatWorks(string responseFormat)
{
AudioClient client = GetTestClient<AudioClient>(TestScenario.Audio_TTS);
AudioClient client = GetProxiedOpenAIClient<AudioClient>(TestScenario.Audio_TTS);

SpeechGenerationOptions options = new();

Expand All @@ -59,9 +58,7 @@ public async Task OutputFormatWorks(string responseFormat)
};
}

BinaryData audio = IsAsync
? await client.GenerateSpeechAsync("Hello, world!", GeneratedSpeechVoice.Alloy, options)
: client.GenerateSpeech("Hello, world!", GeneratedSpeechVoice.Alloy, options);
BinaryData audio = await client.GenerateSpeechAsync("Hello, world!", GeneratedSpeechVoice.Alloy, options);

Assert.That(audio, Is.Not.Null);

Expand All @@ -82,10 +79,10 @@ public async Task OutputFormatWorks(string responseFormat)
}
}

private void ValidateGeneratedAudio(BinaryData audio, string expectedSubstring)
private async Task ValidateGeneratedAudio(BinaryData audio, string expectedSubstring)
{
AudioClient client = GetTestClient<AudioClient>(TestScenario.Audio_Whisper);
AudioTranscription transcription = client.TranscribeAudio(audio.ToStream(), "hello_world.wav");
AudioClient client = GetProxiedOpenAIClient<AudioClient>(TestScenario.Audio_Whisper);
AudioTranscription transcription = await client.TranscribeAudioAsync(audio.ToStream(), "hello_world.wav");

Assert.That(transcription.Text.ToLowerInvariant(), Contains.Substring(expectedSubstring));
}
Expand Down
37 changes: 13 additions & 24 deletions tests/Audio/TranscriptionMockTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.ClientModel.TestFramework;
using Microsoft.ClientModel.TestFramework.Mocks;
using NUnit.Framework;
using OpenAI.Audio;
using OpenAI.Tests.Utility;

namespace OpenAI.Tests.Audio;

[TestFixture(true)]
[TestFixture(false)]
[Parallelizable(ParallelScope.All)]
[Category("Audio")]
[Category("Smoke")]
public partial class TranscriptionMockTests : SyncAsyncTestBase
public partial class TranscriptionMockTests : ClientTestBase
{
private static readonly ApiKeyCredential s_fakeCredential = new ApiKeyCredential("key");

Expand Down Expand Up @@ -141,53 +140,43 @@ public async Task TranscribeAudioDeserializesSegment(AudioSourceKind audioSource
[Test]
public void TranscribeAudioFromStreamRespectsTheCancellationToken()
{
AudioClient client = new AudioClient("model", s_fakeCredential);
AudioClient client = CreateProxyFromClient(new AudioClient("model", s_fakeCredential));
using Stream stream = new MemoryStream();
using CancellationTokenSource cancellationSource = new();
cancellationSource.Cancel();

if (IsAsync)
{
Assert.That(async () => await client.TranscribeAudioAsync(stream, "filename", cancellationToken: cancellationSource.Token),
Assert.That(async () => await client.TranscribeAudioAsync(stream, "filename", cancellationToken: cancellationSource.Token),
Throws.InstanceOf<OperationCanceledException>());
}
else
{
Assert.That(() => client.TranscribeAudio(stream, "filename", cancellationToken: cancellationSource.Token),
Throws.InstanceOf<OperationCanceledException>());
}
}

private OpenAIClientOptions GetClientOptionsWithMockResponse(int status, string content)
{
MockPipelineResponse response = new MockPipelineResponse(status);
response.SetContent(content);
MockPipelineResponse response = new MockPipelineResponse(status).WithContent(content);

return new OpenAIClientOptions()
{
Transport = new MockPipelineTransport(response)
Transport = new MockPipelineTransport(_ => response)
{
ExpectSyncPipeline = !IsAsync
}
};
}

private async ValueTask<AudioTranscription> InvokeTranscribeAudioSyncOrAsync(OpenAIClientOptions clientOptions, AudioSourceKind audioSourceKind)
{
AudioClient client = new AudioClient("model", s_fakeCredential, clientOptions);
AudioClient client = CreateProxyFromClient(new AudioClient("model", s_fakeCredential, clientOptions));
string filename = "audio_french.wav";
string path = Path.Combine("Assets", filename);

if (audioSourceKind == AudioSourceKind.UsingStream)
{
using FileStream audio = File.OpenRead(path);

return IsAsync
? await client.TranscribeAudioAsync(audio, filename)
: client.TranscribeAudio(audio, filename);
return await client.TranscribeAudioAsync(audio, filename);
}
else if (audioSourceKind == AudioSourceKind.UsingFilePath)
{
return IsAsync
? await client.TranscribeAudioAsync(path)
: client.TranscribeAudio(path);
return await client.TranscribeAudioAsync(path);
}

Assert.Fail("Invalid source kind.");
Expand Down
Loading