xUnit Integration
Run your xUnit tests as usual and have results automatically reported to TMS. The SDK uses xUnit's IClassFixture pattern for clean lifecycle management.
Install
The packages are served from the ProvaLab NuGet feed, not nuget.org. Add the feed next to your .sln:
NuGet.config
<configuration>
<packageSources>
<add key="provalab" value="https://plugins.provalab.io/nuget/index.json" />
</packageSources>
</configuration>
Then install:
dotnet add package TMS.SDK --version 1.1.0 --source provalab
Or add to your .csproj:
MyTests.csproj
<ItemGroup>
<PackageReference Include="TMS.SDK" Version="1.1.0" />
</ItemGroup>
Requirements: .NET 6.0+, xUnit 2.5+
Configure
1. Set environment variables
export TMS_API_KEY=your-api-key
export TMS_API_URL=https://tms.yourcompany.com
export TMS_ORGANIZATION_ID=1
export TMS_PROJECT_ID=12
On Windows (PowerShell):
$env:TMS_API_KEY = "your-api-key"
$env:TMS_API_URL = "https://tms.yourcompany.com"
$env:TMS_ORGANIZATION_ID = "1"
$env:TMS_PROJECT_ID = "12"
2. Create a TMS fixture
Tests/TMSFixture.cs
using TMS.SDK;
using Xunit;
public class TMSTestRunFixture : IAsyncLifetime
{
public TMSTestRunManager RunManager { get; private set; }
public async Task InitializeAsync()
{
RunManager = new TMSTestRunManager();
await RunManager.StartRunAsync("xUnit Regression Tests");
}
public async Task DisposeAsync()
{
await RunManager.CompleteRunAsync();
}
}
[CollectionDefinition("TMS")]
public class TMSCollection : ICollectionFixture<TMSTestRunFixture> { }
3. Add TMS attributes to your tests
Tests/LoginTests.cs
using TMS.SDK;
using Xunit;
[Collection("TMS")]
public class LoginTests
{
private readonly TMSTestRunFixture _tms;
public LoginTests(TMSTestRunFixture tms)
{
_tms = tms;
}
[Fact]
[TMSTestCase("TC-101")]
public void ShouldLoginWithValidCredentials()
{
var result = AuthService.Login("[email protected]", "password123");
Assert.True(result.IsSuccess);
}
[Fact]
[TMSTestCase("TC-102")]
public void ShouldRejectInvalidPassword()
{
Assert.Throws<AuthException>(() =>
{
AuthService.Login("[email protected]", "wrong-password");
});
}
[Fact]
[TMSTestCase("TC-103")]
public void ShouldHandleExpiredAccount()
{
Assert.Throws<AccountExpiredException>(() =>
{
AuthService.Login("[email protected]", "password123");
});
}
}
Run
dotnet test
You'll see TMS output alongside xUnit's normal output:
TMS xUnit Integration
Test Run ID: 858
Project ID: 12
[PASS] LoginTests.ShouldLoginWithValidCredentials (0.12s)
[PASS] LoginTests.ShouldRejectInvalidPassword (0.08s)
[FAIL] LoginTests.ShouldHandleExpiredAccount (0.15s)
TMS Test Run Summary
Test Run ID: 858
Total: 3, Passed: 2, Failed: 1, Skipped: 0
View Results in TMS
- Open TMS and go to your project
- Click Test Runs in the sidebar
- Find the run named "xUnit Regression Tests"
- Click into it to see individual test results with error details
Advanced Configuration
Theory (parameterized) tests
[Theory]
[TMSTestCase("TC-201")]
[InlineData("[email protected]", "admin123", true)]
[InlineData("[email protected]", "user123", true)]
[InlineData("[email protected]", "wrong", false)]
public void ShouldHandleLogin(string email, string password, bool expected)
{
var result = AuthService.Login(email, password);
Assert.Equal(expected, result.IsSuccess);
}
Each InlineData set is reported as a separate result in TMS.
Using IClassFixture for per-class setup
If you want a separate test run per test class:
public class LoginTests : IClassFixture<TMSClassFixture>
{
private readonly TMSClassFixture _tms;
public LoginTests(TMSClassFixture tms)
{
_tms = tms;
}
[Fact]
[TMSTestCase("TC-101")]
public void ShouldLogin()
{
Assert.True(true);
}
}
Configuration via appsettings.json
appsettings.json
{
"TMS": {
"ApiUrl": "https://tms.yourcompany.com",
"ApiKey": "your-api-key",
"OrganizationId": 1,
"ProjectId": 12,
"Environment": "staging"
}
}
Disable TMS for local development
export TMS_DISABLED=true
dotnet test
Run specific tests
dotnet test --filter "FullyQualifiedName~LoginTests"
With dependency injection
xUnit supports constructor injection. Combine with TMS:
[Collection("TMS")]
public class ApiTests
{
private readonly TMSTestRunFixture _tms;
private readonly HttpClient _client;
public ApiTests(TMSTestRunFixture tms)
{
_tms = tms;
_client = new HttpClient { BaseAddress = new Uri("https://api.yourcompany.com") };
}
[Fact]
[TMSTestCase("TC-301")]
public async Task ShouldReturnUsers()
{
var response = await _client.GetAsync("/api/users");
Assert.True(response.IsSuccessStatusCode);
}
}
Verify It Works
- Install the package (with the ProvaLab feed in
NuGet.config, see Install):
dotnet add package TMS.SDK --version 1.1.0 --source provalab
- Set your environment variables
- Create the fixture and a simple test:
Tests/TMSVerifyTest.cs
using TMS.SDK;
using Xunit;
[Collection("TMS")]
public class TMSVerifyTest
{
public TMSVerifyTest(TMSTestRunFixture tms) { }
[Fact]
[TMSTestCase("TC-1")]
public void VerifyTmsIntegration()
{
Assert.Equal(2, 1 + 1);
}
}
- Run:
dotnet test --filter TMSVerifyTest - Check the console for the TMS summary
- Open TMS and confirm the test run appears
Common issues
- "Not configured" message: Make sure environment variables are set in your shell session
- Fixture not initializing: Ensure
[Collection("TMS")]is on your test class and theTMSCollectiondefinition exists - Package not found: Check that your NuGet feed includes the TMS package repository