Saucery.TUnit
0.20.16
Prefix Reserved
See the version list below for details.
dotnet add package Saucery.TUnit --version 0.20.16
NuGet\Install-Package Saucery.TUnit -Version 0.20.16
<PackageReference Include="Saucery.TUnit" Version="0.20.16" />
<PackageVersion Include="Saucery.TUnit" Version="0.20.16" />
<PackageReference Include="Saucery.TUnit" />
paket add Saucery.TUnit --version 0.20.16
#r "nuget: Saucery.TUnit, 0.20.16"
#:package Saucery.TUnit@0.20.16
#addin nuget:?package=Saucery.TUnit&version=0.20.16
#tool nuget:?package=Saucery.TUnit&version=0.20.16
Saucery.TUnit
Saucery handles all the plumbing required to integrate with SauceLabs, making writing TUnit tests a breeze, so you only need to tell Saucery what you want. Saucery takes care of the how.
Note: The tests specified below are provided as examples only. Your tests, of course, will be specific to your System Under Test.
Sponsoring
Saucery has been developed as an open-source project for over 10 years. If you find it valuable for your projects and team work, please consider supporting it and becoming a
IDE Setup
If you are using Visual Studio 17.12 or earlier, follow the instructions here to set up your IDE.
Initial Setup
- You'll need a SauceLabs account. You can get a free trial account here.
- If you want to run your tests locally you need to set 2 environment variables, SAUCE_USER_NAME and SAUCE_API_KEY
- To run your test suite from your GitHub Actions pipeline you need to set two secrets SAUCE_USER_NAME and SAUCE_API_KEY. Instructions on how to set Github Secrets are here.
Writing TUnit Tests
- In your solution create a simple class library.
- Add a NuGet Reference to Saucery.TUnit.
Your Project file should look something like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Saucery.TUnit" Version="0.16.4" />
</ItemGroup>
</Project>
The ExternalMerlin.TUnit dogfood integration tests use the following template:
using Saucery.Core.Dojo;
using Saucery.Tests.Common.PageObjects;
using Saucery.TUnit;
namespace Merlin.TUnit;
public class DataDrivenTests : SauceryTBase
{
[Test]
[MethodDataSource(nameof(AllCombinations), Arguments = [new[] { 4, 5 }])]
public async Task DataDrivenTest(BrowserVersion requestedPlatform, int data)
{
InitialiseDriver(requestedPlatform);
var guineaPigPage = new GuineaPigPage(SauceryDriver(), "https://saucelabs.com/");
guineaPigPage.TypeField(SauceryDriver(), "comments", data.ToString());
var commentField = guineaPigPage.GetField(SauceryDriver(), "comments");
await Assert.That(commentField).IsNotNull();
var commentText = commentField.GetDomProperty("value");
await Assert.That(commentText).Contains(data.ToString());
}
public static IEnumerable<Func<(BrowserVersion, int)>> AllCombinations(int[] data) =>
RequestedPlatformData
.AllPlatforms()
.SelectMany(
_ => data,
(browserVersionFunc, datum) => new Func<(BrowserVersion, int)>(() => (browserVersionFunc(), datum))
);
}
The above code will run 2 unit tests (2 DataDrivenTitle tests) on all the platforms you specify, in parallel by default.
Parallelism
- Parallelism in TUnit is default out of the box. For SauceLabs it needs to be constrained.
- Have a look at MyParallelLimit.cs in the ExternalMerlin.TUnit project for an example of how to do that.
- We recommend 2 less than your limit. Our OpenSauce account has 5 so we specify 3 in our internal testing.
The other lines are mandatory. Let's break the key lines down.
public class DataDrivenTests : SauceryTBase
Your class must subclass SauceryTBase. SauceryT will take care of the rest.
A data driven test is specified like this:
[Test]
[MethodDataSource(nameof(AllCombinations), Arguments = [new[] { 4, 5 }])]
public async Task DataDrivenTest(Func<BrowserVersion> requestedPlatform, int data)
You can call the class what you like but it must take a Func<BrowserVersion> and the data as a parameter and subclass SauceryTBase.
[MethodDataSource(nameof(AllCombinations)...] is how you tell SauceryT what platforms you want to test on. You need to specify a class to do that. In this example its called RequestedPlatformData but you can call it anything you like.
Let's look at what it should contain.
using Saucery.Core.DataSources;
using Saucery.Core.Dojo;
using Saucery.Core.OnDemand;
using Saucery.Core.OnDemand.Base;
using Saucery.Core.Util;
namespace ExternalMerlin.TUnit;
public class RequestedPlatformData : SauceryTestData
{
static RequestedPlatformData()
{
var platforms = new List<SaucePlatform>
{
//Emulated Mobile Platforms
new AndroidPlatform("Google Pixel 8 Pro GoogleAPI Emulator", "15.0", SauceryConstants.DEVICE_ORIENTATION_PORTRAIT),
new IOSPlatform("iPhone 14 Pro Max Simulator", "16.2", SauceryConstants.DEVICE_ORIENTATION_LANDSCAPE),
//Desktop Platforms
new DesktopPlatform(SauceryConstants.PLATFORM_WINDOWS_11, SauceryConstants.BROWSER_CHROME, "123"),
new DesktopPlatform(SauceryConstants.PLATFORM_WINDOWS_10, SauceryConstants.BROWSER_CHROME, "124", SauceryConstants.SCREENRES_2560_1600)
};
SetPlatforms(platforms, PlatformFilter.Emulated);
}
public static List<Func<BrowserVersion>> AllPlatforms() => GetAllPlatformsAsFunc();
}
The List<SaucePlatform> is what you will specify. The rest of the class is mandatory. Check out SauceryConstants for all the platform, browser and screenres enums.
Platform Range Expansion
Platform range expansion is a feature unique to Saucery. Say you wanted to test on a range of browser versions but you didn't want to specify each individually. That's fine. Saucery supports specifying ranges.
new DesktopPlatform(SauceryConstants.PLATFORM_WINDOWS_11, SauceryConstants.BROWSER_CHROME, "100->119")
This will test on Windows 11 Chrome all available versions from 100 to 119 inclusive.
Real Devices
Yes, Saucery supports Real Devices!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Microsoft.CodeCoverage (>= 17.13.0)
- Microsoft.NET.Test.Sdk (>= 17.13.0)
- Saucery.Core (>= 4.5.32)
- TUnit (>= 0.20.16)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.13.51 | 23 | 2/12/2026 |
| 1.13.48 | 26 | 2/12/2026 |
| 1.13.47 | 35 | 2/12/2026 |
| 1.13.40 | 36 | 2/11/2026 |
| 1.13.30 | 41 | 2/11/2026 |
| 1.13.27 | 35 | 2/11/2026 |
| 1.13.24 | 40 | 2/10/2026 |
| 1.13.11 | 90 | 2/7/2026 |
| 1.13.8 | 84 | 2/7/2026 |
| 1.13.0 | 77 | 2/6/2026 |
| 1.12.147 | 84 | 2/6/2026 |
| 1.12.144 | 84 | 2/6/2026 |
| 1.12.139 | 88 | 2/5/2026 |
| 1.12.125 | 113 | 2/3/2026 |
| 1.12.111 | 101 | 2/1/2026 |
| 1.12.102 | 95 | 1/31/2026 |
| 1.12.93 | 110 | 1/29/2026 |
| 1.12.90 | 81 | 1/29/2026 |
| 1.12.86 | 85 | 1/29/2026 |
| 0.20.16 | 263 | 5/19/2025 |
ChangeLog:
v4.0.0
- Initial Release with dependency on Saucery.Core