Saucery.TUnit 0.20.0

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Saucery.TUnit --version 0.20.0
                    
NuGet\Install-Package Saucery.TUnit -Version 0.20.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Saucery.TUnit" Version="0.20.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Saucery.TUnit" Version="0.20.0" />
                    
Directory.Packages.props
<PackageReference Include="Saucery.TUnit" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Saucery.TUnit --version 0.20.0
                    
#r "nuget: Saucery.TUnit, 0.20.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Saucery.TUnit@0.20.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Saucery.TUnit&version=0.20.0
                    
Install as a Cake Addin
#tool nuget:?package=Saucery.TUnit&version=0.20.0
                    
Install as a Cake Tool

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 alternate text is missing from this package README image

IDE Setup

If you are using Visual Studio 17.12 or earlier, follow the instructions here to set up your IDE.

Initial Setup

  1. You'll need a SauceLabs account. You can get a free trial account here.
  2. If you want to run your tests locally you need to set 2 environment variables, SAUCE_USER_NAME and SAUCE_API_KEY
  3. 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

  1. In your solution create a simple class library.
  2. 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.40 0 2/11/2026
1.13.30 0 2/11/2026
1.13.27 0 2/11/2026
1.13.24 19 2/10/2026
1.13.11 87 2/7/2026
1.13.8 82 2/7/2026
1.13.0 76 2/6/2026
1.12.147 83 2/6/2026
1.12.144 83 2/6/2026
1.12.139 87 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
1.12.82 97 1/29/2026
1.12.80 84 1/29/2026
1.12.65 100 1/27/2026
1.12.58 92 1/27/2026
1.12.53 114 1/25/2026
1.12.43 154 1/24/2026
1.12.41 85 1/24/2026
1.12.15 200 1/20/2026
1.12.3 95 1/18/2026
1.12.0 95 1/18/2026
1.11.64 97 1/18/2026
1.11.56 108 1/17/2026
1.11.51 99 1/16/2026
1.11.45 95 1/16/2026
1.11.28 104 1/15/2026
1.11.18 94 1/14/2026
1.11.16 92 1/14/2026
1.11.0 92 1/14/2026
1.10.0 98 1/13/2026
1.9.91 90 1/13/2026
1.9.85 92 1/12/2026
1.9.81 95 1/12/2026
1.9.68 94 1/12/2026
1.9.64 97 1/11/2026
1.9.55 101 1/10/2026
1.9.45 102 1/10/2026
1.9.26 107 1/8/2026
1.9.2 170 1/4/2026
1.9.0 98 1/4/2026
1.8.9 101 1/4/2026
1.8.1 119 1/3/2026
1.8.0 117 1/3/2026
1.7.20 121 1/2/2026
1.7.16 105 1/1/2026
1.7.7 182 12/30/2025
1.7.5 113 12/29/2025
1.7.0 154 12/28/2025
1.6.28 389 12/25/2025
1.6.27 190 12/24/2025
1.6.25 197 12/24/2025
1.6.20 189 12/23/2025
1.6.15 189 12/22/2025
1.6.5 195 12/21/2025
1.6.0 128 12/21/2025
1.5.80 235 12/20/2025
1.5.78 197 12/19/2025
1.5.70 300 12/18/2025
1.5.60 219 12/14/2025
1.5.53 188 12/12/2025
1.5.48 147 12/12/2025
1.5.42 146 12/12/2025
1.5.41 439 12/11/2025
1.5.37 438 12/11/2025
1.5.35 440 12/11/2025
1.5.33 431 12/10/2025
1.5.6 335 12/8/2025
1.5.1 320 12/7/2025
1.5.0 230 12/7/2025
1.4.8 231 12/7/2025
1.4.7 225 12/7/2025
1.4.5 145 12/6/2025
1.4.0 191 12/6/2025
1.3.25 263 12/3/2025
1.3.15 534 12/1/2025
1.3.13 445 12/1/2025
1.3.9 374 11/30/2025
1.3.0 288 11/30/2025
1.2.11 523 11/19/2025
1.2.3 313 11/17/2025
1.2.0 188 11/15/2025
1.1.27 259 11/15/2025
1.1.10 399 11/13/2025
1.1.0 319 11/13/2025
1.0.78 354 11/12/2025
1.0.48 320 11/10/2025
1.0.39 249 11/10/2025
1.0.30 283 11/8/2025
1.0.27 137 11/8/2025
1.0.0 208 11/6/2025
0.90.45 203 11/6/2025
0.90.42 208 11/6/2025
0.90.38 206 11/6/2025
0.90.35 198 11/6/2025
0.90.32 203 11/6/2025
0.90.28 207 11/6/2025
0.90.19 259 11/3/2025
0.90.17 203 11/3/2025
0.90.6 235 11/2/2025
0.90.0 203 11/2/2025
0.89.2 181 11/2/2025
0.89.0 201 11/2/2025
0.88.0 143 11/2/2025
0.87.8 140 11/1/2025
0.86.10 228 10/31/2025
0.86.5 212 10/31/2025
0.86.0 232 10/30/2025
0.85.1 212 10/30/2025
0.85.0 206 10/30/2025
0.81.7 207 10/30/2025
0.81.0 219 10/30/2025
0.80.0 317 10/29/2025
0.79.0 216 10/29/2025
0.78.0 202 10/29/2025
0.77.10 207 10/29/2025
0.77.3 226 10/27/2025
0.77.0 225 10/26/2025
0.76.26 216 10/26/2025
0.76.18 287 10/26/2025
0.76.11 210 10/25/2025
0.76.7 152 10/25/2025
0.76.0 122 10/25/2025
0.75.30 223 10/23/2025
0.75.11 194 10/23/2025
0.75.5 200 10/23/2025
0.75.4 204 10/23/2025
0.75.0 209 10/22/2025
0.74.2 209 10/21/2025
0.74.0 198 10/21/2025
0.73.19 247 10/19/2025
0.73.14 132 10/18/2025
0.73.11 109 10/18/2025
0.73.4 196 10/17/2025
0.73.0 192 10/16/2025
0.72.0 209 10/15/2025
0.71.4 208 10/15/2025
0.71.0 196 10/15/2025
0.70.7 196 10/15/2025
0.70.4 192 10/15/2025
0.70.2 222 10/13/2025
0.70.0 197 10/13/2025
0.67.19 145 10/11/2025
0.67.10 252 10/8/2025
0.67.9 185 10/8/2025
0.67.4 215 10/8/2025
0.67.0 262 10/7/2025
0.66.13 206 10/7/2025
0.66.6 276 10/6/2025
0.66.0 242 10/5/2025
0.64.0 188 10/5/2025
0.63.3 264 10/3/2025
0.63.0 187 10/3/2025
0.61.58 271 9/29/2025
0.61.39 293 9/26/2025
0.61.38 180 9/26/2025
0.61.31 244 9/25/2025
0.61.25 219 9/24/2025
0.61.22 219 9/23/2025
0.61.13 337 9/22/2025
0.61.6 242 9/22/2025
0.61.2 260 9/21/2025
0.60.1 272 9/19/2025
0.59.0 245 9/19/2025
0.58.3 243 9/19/2025
0.58.0 297 9/19/2025
0.57.65 311 9/12/2025
0.57.63 173 9/12/2025
0.57.24 368 8/31/2025
0.57.1 163 8/23/2025
0.57.0 118 8/23/2025
0.56.50 218 8/20/2025
0.56.44 186 8/20/2025
0.56.35 189 8/20/2025
0.56.5 294 8/16/2025
0.55.21 125 8/16/2025
0.55.6 286 8/13/2025
0.55.0 202 8/13/2025
0.53.0 639 8/9/2025
0.52.64 271 8/8/2025
0.52.60 265 8/8/2025
0.52.56 267 8/8/2025
0.52.51 268 8/8/2025
0.52.49 344 8/7/2025
0.50.0 335 8/5/2025
0.25.21 1,251 6/12/2025
0.25.6 470 6/9/2025
0.23.0 251 6/2/2025
0.22.31 298 5/31/2025
0.22.24 258 5/29/2025
0.22.20 224 5/29/2025
0.22.12 226 5/29/2025
0.22.10 258 5/25/2025
0.22.6 198 5/25/2025
0.22.0 259 5/23/2025
0.21.16 249 5/22/2025
0.21.13 241 5/22/2025
0.21.7 223 5/22/2025
0.21.1 233 5/22/2025
0.20.18 261 5/22/2025
0.20.16 263 5/19/2025
0.20.11 234 5/19/2025
0.20.4 205 5/17/2025
0.20.0 290 5/16/2025
0.19.148 297 5/16/2025
0.19.143 275 5/16/2025
0.19.140 320 5/11/2025
0.19.136 227 5/11/2025
0.19.116 376 5/3/2025
0.19.112 156 5/2/2025
0.19.86 338 4/20/2025
0.19.84 231 4/20/2025
0.19.82 305 4/16/2025
0.19.81 290 4/16/2025
0.19.74 294 4/16/2025
0.19.64 334 4/10/2025
0.19.52 327 4/8/2025
0.19.32 393 4/1/2025
0.19.24 269 3/28/2025
0.19.14 237 3/28/2025
0.19.10 296 3/27/2025
0.19.6 226 3/27/2025
0.19.4 610 3/26/2025
0.19.2 565 3/26/2025
0.19.0 570 3/26/2025
0.18.60 204 3/22/2025
0.18.52 306 3/20/2025
0.18.45 287 3/19/2025
0.18.40 289 3/17/2025
0.18.33 267 3/16/2025
0.18.26 262 3/13/2025
0.18.24 232 3/13/2025
0.18.23 240 3/13/2025
0.18.21 247 3/13/2025
0.18.17 248 3/13/2025
0.18.16 205 3/13/2025
0.18.9 291 3/11/2025
0.18.0 266 3/11/2025
0.17.14 256 3/11/2025
0.17.11 264 3/11/2025
0.17.8 248 3/11/2025
0.17.3 297 3/10/2025
0.17.0 296 3/9/2025
0.16.56 255 3/9/2025
0.16.54 234 3/9/2025
0.16.50 201 3/9/2025
0.16.49 211 3/9/2025
0.16.47 223 3/9/2025
0.16.45 221 3/9/2025
0.16.42 196 3/9/2025
0.16.36 334 3/8/2025
0.16.28 296 3/6/2025
0.16.23 319 3/6/2025
0.16.22 317 3/6/2025
0.16.13 322 3/4/2025
0.16.11 362 3/4/2025
0.16.8 416 3/4/2025
0.16.6 304 3/4/2025
0.16.4 248 3/3/2025
0.16.1 239 3/2/2025
0.15.30 224 2/28/2025
0.15.18 240 2/28/2025
0.15.3 207 2/28/2025
0.15.1 160 2/28/2025
0.14.17 291 2/26/2025
0.14.13 259 2/26/2025
0.14.10 204 2/24/2025
0.14.6 261 2/23/2025
0.14.0 268 2/21/2025
0.13.25 248 2/21/2025
0.13.23 183 2/20/2025
0.13.20 231 2/19/2025
0.13.18 244 2/19/2025
0.13.15 205 2/19/2025
0.13.13 197 2/19/2025
0.13.9 267 2/18/2025
0.13.3 246 2/17/2025
0.13.0 312 2/16/2025
0.12.25 209 2/15/2025
0.12.23 231 2/15/2025
0.12.21 217 2/14/2025
0.12.17 338 2/14/2025
0.12.14 211 2/14/2025
0.12.13 185 2/14/2025
0.12.11 195 2/14/2025
0.12.6 334 2/13/2025
0.12.0 229 2/12/2025
0.11.0 355 2/8/2025
0.10.28 257 2/6/2025
0.10.26 196 2/6/2025
0.10.19 219 2/5/2025
0.10.6 251 2/3/2025
0.10.4 230 2/3/2025
0.10.1 215 2/2/2025
0.9.11 306 2/2/2025
0.9.2 227 2/1/2025
0.9.0 348 1/31/2025
0.8.12 352 1/29/2025
0.8.4 232 1/29/2025
0.8.2 233 1/28/2025
0.7.19 251 1/27/2025
0.7.9 390 1/25/2025
0.7.3 242 1/24/2025
0.7.0 237 1/23/2025
0.6.159 226 1/21/2025
0.6.154 307 1/21/2025
0.6.151 286 1/19/2025
0.6.145 175 1/19/2025
0.6.137 239 1/19/2025
0.6.123 293 1/18/2025
0.6.117 272 1/17/2025
0.6.100 218 1/14/2025
0.6.89 246 1/12/2025
0.6.81 236 1/11/2025
0.6.43 282 1/9/2025
0.6.33 264 1/5/2025
0.6.15 277 1/2/2025
0.6.0 370 12/28/2024
0.5.22 291 12/21/2024
0.5.6 361 12/18/2024

ChangeLog:
 v4.0.0
 - Initial Release with dependency on Saucery.Core