GetSkipper.MSTest
1.1.0
dotnet add package GetSkipper.MSTest --version 1.1.0
NuGet\Install-Package GetSkipper.MSTest -Version 1.1.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="GetSkipper.MSTest" Version="1.1.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GetSkipper.MSTest" Version="1.1.0" />
<PackageReference Include="GetSkipper.MSTest" />
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 GetSkipper.MSTest --version 1.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: GetSkipper.MSTest, 1.1.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 GetSkipper.MSTest@1.1.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=GetSkipper.MSTest&version=1.1.0
#tool nuget:?package=GetSkipper.MSTest&version=1.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
skipper-dotnet
Test-gating for .NET — skip tests dynamically via a Google Spreadsheet, without touching your test code.
What is Skipper?
Skipper reads a Google Spreadsheet to decide which tests to skip. Each row has:
| testId | disabledUntil | notes |
|---|---|---|
Tests/Unit/AuthTests.cs > AuthTests > CanLogin |
2026-06-01 |
Flaky on CI |
Tests/E2E/LoginTests.cs > LoginTests > UserCanLogin |
disabledUntilis in the future → test is skipped automaticallydisabledUntilis empty or in the past → test runs normally- Test not in spreadsheet → test runs normally (opt-out model)
No code changes required in your tests. Configure once, gate everywhere.
Packages
| Package | Description | NuGet |
|---|---|---|
GetSkipper.Core |
Google Sheets client, resolver, writer | |
GetSkipper.XUnit |
xUnit v2/v3 integration | |
GetSkipper.NUnit |
NUnit 3/4 integration | |
GetSkipper.MSTest |
MSTest v3 integration | |
GetSkipper.Playwright |
Playwright for .NET | |
GetSkipper.SpecFlow |
Reqnroll (SpecFlow) BDD |
Quick Start
xUnit (zero changes to your tests)
// AssemblyInfo.cs — add once to your test project
using GetSkipper.XUnit;
[assembly: TestFramework("GetSkipper.XUnit.SkipperTestFramework", "GetSkipper.XUnit")]
[assembly: SkipperConfig(
SpreadsheetIdEnvVar = "SKIPPER_SPREADSHEET_ID",
CredentialsFile = "service-account.json")]
// Your tests remain unchanged:
public class AuthTests
{
[Fact]
public void CanLogin() { /* ... */ }
}
NUnit (zero changes to your tests)
// AssemblyInfo.cs
using GetSkipper.NUnit;
[assembly: SkipperConfig(
SpreadsheetId = "1abc...",
CredentialsFile = "service-account.json")]
// Your tests remain unchanged:
[TestFixture]
public class AuthTests
{
[Test]
public void CanLogin() { /* ... */ }
}
MSTest (zero changes to your tests)
// SkipperSetup.cs — add once to your test project
using GetSkipper.Core;
using GetSkipper.Core.Credentials;
using GetSkipper.MSTest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
public static class SkipperSetup
{
[GlobalTestInitialize]
public static async Task InitAsync()
=> await SkipperGlobalHooks.ConfigureAsync(new SkipperConfig
{
SpreadsheetId = "1abc...",
Credentials = new FileCredentials("service-account.json"),
});
[GlobalTestCleanup]
public static Task CleanupAsync() => SkipperGlobalHooks.AfterAllTestsAsync();
}
// Intercept each test (call from a second [GlobalTestInitialize] or use one method):
public static class SkipperTestGate
{
[GlobalTestInitialize]
public static void BeforeTest(TestContext ctx) => SkipperGlobalHooks.BeforeTest(ctx);
}
Playwright (change base class only)
using GetSkipper.NUnit;
using GetSkipper.Playwright;
[assembly: SkipperConfig(SpreadsheetId = "1abc...", CredentialsFile = "service-account.json")]
[TestFixture]
public class LoginTests : SkipperPageTest // was: PageTest
{
[Test]
public async Task UserCanLogin()
{
await Page.GotoAsync("/login");
// automatic skip is handled before this line
}
}
Reqnroll / SpecFlow (zero changes to step definitions)
// reqnroll.json
{
"bindingAssemblies": [
{ "assembly": "GetSkipper.SpecFlow" }
]
}
SKIPPER_SPREADSHEET_ID=1abc... SKIPPER_CREDENTIALS_FILE=./service-account.json dotnet test
Spreadsheet Format
| Column | Required | Description |
|---|---|---|
testId |
Yes | Canonical test identifier |
disabledUntil |
No | ISO-8601 date (2026-06-01). Empty = enabled |
notes |
No | Free text |
Test ID formats
| Framework | Format |
|---|---|
| xUnit / NUnit / MSTest | Tests/Unit/AuthTests.cs > AuthTests > CanLogin |
| Playwright | Tests/E2E/LoginTests.cs > LoginTests > UserCanLogin |
| Reqnroll | Features/Auth/Login.feature > User authentication > User can log in |
Sync Mode
Reconcile the spreadsheet with your test suite (append new tests, remove deleted ones):
SKIPPER_MODE=sync dotnet test
Typically run on main after all tests pass:
# .github/workflows/ci.yml
- name: Run tests in sync mode
if: github.ref == 'refs/heads/main'
env:
SKIPPER_MODE: sync
SKIPPER_SPREADSHEET_ID: ${{ secrets.SKIPPER_SPREADSHEET_ID }}
GOOGLE_CREDS_B64: ${{ secrets.GOOGLE_CREDS_B64 }}
run: dotnet test
Credentials
Three ways to supply the Google service account:
// 1. JSON file (local dev)
Credentials = new FileCredentials("./service-account.json")
// 2. Base-64 encoded JSON (CI secrets)
Credentials = new Base64Credentials(Environment.GetEnvironmentVariable("GOOGLE_CREDS_B64")!)
// 3. Inline object
Credentials = new ServiceAccountCredentials(
clientEmail: "skipper@project.iam.gserviceaccount.com",
privateKey: "-----BEGIN RSA PRIVATE KEY-----\n...")
Environment Variables
| Variable | Default | Description |
|---|---|---|
SKIPPER_MODE |
read-only |
Set to sync to reconcile spreadsheet |
SKIPPER_SPREADSHEET_ID |
— | Spreadsheet ID (used with SpreadsheetIdEnvVar) |
GOOGLE_CREDS_B64 |
— | Base-64 credentials (used with CredentialsEnvVar) |
SKIPPER_DEBUG |
— | Set to any value for verbose logging |
License
MIT — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. 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.
-
net8.0
- GetSkipper.Core (>= 1.1.0)
- MSTest.TestFramework (>= 3.6.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.