Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/docs/writing-tests/artifacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ TUnit supports attaching artifacts at two levels:

Attach files to individual tests using `TestContext.Current.Output.AttachArtifact()`.

### Writing Artifacts to the Results Directory

Use `TestContext.ResultsDirectory` to place generated files alongside reports and other
artifacts. The property returns the absolute directory selected by Microsoft.Testing.Platform,
including any `--results-directory` override.

```csharp
[Test]
public async Task CaptureLog()
{
var artifactPath = Path.Combine(TestContext.ResultsDirectory, "application.log");

await File.WriteAllTextAsync(artifactPath, "Diagnostic information");
TestContext.Current!.Output.AttachArtifact(artifactPath);
}
```

### Basic Usage

The simplest way to attach an artifact is by providing just the file path:
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/writing-tests/test-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ Both `Output.WriteLine()` and `OutputWriter.WriteLine()` are valid - the `Output

Artifacts are particularly useful for debugging test failures, especially in integration tests. You can attach screenshots, logs, videos, configuration files, or any other files that help diagnose issues.

Use `TestContext.ResultsDirectory` to get the absolute Microsoft.Testing.Platform results
directory. It respects configuration such as `--results-directory` and is suitable for files
that should live alongside test reports.

For complete information about working with test artifacts, including session-level artifacts, best practices, and common use cases, see the [Test Artifacts](./artifacts.md) guide.

## Test Isolation
Expand Down
17 changes: 17 additions & 0 deletions src/TUnit.Core/TestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ public ContextScope MakeCurrent()
public static IReadOnlyDictionary<string, List<string>> Parameters => InternalParametersDictionary;

private static IConfiguration? _configuration;
private static string? _resultsDirectory;

/// <summary>
/// Gets the test configuration. Throws a descriptive exception if accessed before initialization.
Expand All @@ -246,6 +247,22 @@ public static IConfiguration Configuration
internal set => _configuration = value;
}

/// <summary>
/// Gets the absolute path to the directory where test results are written.
/// This respects Microsoft.Testing.Platform configuration, including the
/// <c>--results-directory</c> command-line option.
/// </summary>
/// <exception cref="InvalidOperationException">Thrown if accessed before the test engine initializes it.</exception>
public static string ResultsDirectory
{
get => _resultsDirectory ?? throw new InvalidOperationException(
"TestContext.ResultsDirectory has not been initialized. " +
"This property is only available after the TUnit test engine has started. " +
"If you are accessing this from a static constructor or field initializer, " +
"consider moving the code to a test setup method or test body instead.");
internal set => _resultsDirectory = value;
}

/// <summary>
/// Gets the output directory of the test assembly, or <c>null</c> if it cannot be determined.
/// This is typically the directory where the test binaries are located.
Expand Down
2 changes: 2 additions & 0 deletions src/TUnit.Engine/Framework/TUnitServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Runtime.CompilerServices;
using Microsoft.Testing.Platform.Capabilities.TestFramework;
using Microsoft.Testing.Platform.CommandLine;
using Microsoft.Testing.Platform.Configurations;
using Microsoft.Testing.Platform.Extensions;
using Microsoft.Testing.Platform.Extensions.TestFramework;
using Microsoft.Testing.Platform.Logging;
Expand Down Expand Up @@ -77,6 +78,7 @@ public TUnitServiceProvider(IExtension extension,
var configuration = frameworkServiceProvider.GetConfiguration();

TestContext.Configuration = new ConfigurationAdapter(configuration);
TestContext.ResultsDirectory = configuration.GetTestResultDirectory();

// Register capabilities so they're available to test contexts
Register<ITestFrameworkCapabilities>(capabilities);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,7 @@ namespace
public new static .TestContext? Current { get; }
public static string? OutputDirectory { get; }
public static .<string, .<string>> Parameters { get; }
public static string ResultsDirectory { get; }
public static string? TestDirectory { get; }
public static string WorkingDirectory { get; set; }
public override string GetErrorOutput() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,7 @@ namespace
public new static .TestContext? Current { get; }
public static string? OutputDirectory { get; }
public static .<string, .<string>> Parameters { get; }
public static string ResultsDirectory { get; }
public static string? TestDirectory { get; }
public static string WorkingDirectory { get; set; }
public override string GetErrorOutput() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,7 @@ namespace
public new static .TestContext? Current { get; }
public static string? OutputDirectory { get; }
public static .<string, .<string>> Parameters { get; }
public static string ResultsDirectory { get; }
public static string? TestDirectory { get; }
public static string WorkingDirectory { get; set; }
public override string GetErrorOutput() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,7 @@ namespace
public new static .TestContext? Current { get; }
public static string? OutputDirectory { get; }
public static .<string, .<string>> Parameters { get; }
public static string ResultsDirectory { get; }
public static string? TestDirectory { get; }
public static string WorkingDirectory { get; set; }
public override string GetErrorOutput() { }
Expand Down
11 changes: 11 additions & 0 deletions tests/TUnit.TestProject/TestContextTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ namespace TUnit.TestProject;
[EngineTest(ExpectedResult.Pass)]
public class TestContextTests
{
[Test]
public async Task ResultsDirectory_Is_Exposed()
{
var resultsDirectory = TestContext.ResultsDirectory;

await Assert.That(Path.IsPathFullyQualified(resultsDirectory)).IsTrue();
await Assert.That(Directory.Exists(resultsDirectory)).IsTrue();
await Assert.That(resultsDirectory)
.IsEqualTo(TestContext.Configuration.Get("platformOptions:resultDirectory"));
}

[Test]
public async Task Test()
{
Expand Down
Loading