peSHIr.XUnit 1.0.1

Prefix Reserved
dotnet add package peSHIr.XUnit --version 1.0.1
                    
NuGet\Install-Package peSHIr.XUnit -Version 1.0.1
                    
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="peSHIr.XUnit" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="peSHIr.XUnit" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="peSHIr.XUnit" />
                    
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 peSHIr.XUnit --version 1.0.1
                    
#r "nuget: peSHIr.XUnit, 1.0.1"
                    
#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 peSHIr.XUnit@1.0.1
                    
#: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=peSHIr.XUnit&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=peSHIr.XUnit&version=1.0.1
                    
Install as a Cake Tool

About

What's this?

This library contains some base classes for unit test fixtures that I have been developing over the last decade or so (some even longer) and that I use extensively in almost anything I write/maintain these days.

What's so special about that?

There might not be anything really special about this, but maybe you think some of this is useful in your daily .NET developing life? These include things like:

  • Specific versions of NuGet packages used for unit tests and assertions in my test code.
  • TestBase base class for test fixtures that contains stuff like:
    • WriteLine() methods to write to ITestOutputHelper
    • implementation of IShowProgress from peSHIr.Core, so you can use the test fixture anywhere IShowProgress can be used
    • convert a simple string into a Stream
    • get different types of random values
    • ignore certain test code until a certain future date
  • LogicFactoryTestBase<TLogic> : TestBase base class with abstract LogicInstanceFactory() override to create an instance of the protected TLogic Logic property for each instance of running any [Fact] or [Theory]
  • LogicTestBase<TLogic> derived from LogicFactoryTestBase for simpler TLogic classes that have a parameter-less constructor.

I know those last two members of TestBase might be a bad idea in unit tests in general, but I have test fixtures that use this on occasion, so these methods are staying in TestBase for my own ease of use.

Who created this?

My name is Jarno Peschier. I started programming on a Commodore 64 in high school, got a masters degree in Computer Science at Utrecht University near the end of the 20th century, specializing in GIS algorithms, and I have been developing software all my professional life.

In 2025 I started publishing some NuGet packages while working as a software engineer at Dutch engineering firm Iv, where I personally handled all software development around our scan vehicle (YouTube) using multiple third party software packages, C#, and PowerShell.

You might also know me by my online name of peSHIr, which is basically the way you write my last name phonetically in Klingon.

How do I use it?

A very simple set of unit tests for instances of Stack, with reuse of some code in particular situation and Test Explorer output of what is happenning gives an example of what this can do:

[Trait("Logic", nameof(System.Collections.Stack))]
public abstract class StackTest(ITestOutputHelper context) : LogicTestBase<System.Collections.Stack>(context)
{
	protected override void LogicInstanceValidityAssertion(System.Collections.Stack logic, bool expectedToBeValid = true)
	{
		base.LogicInstanceValidityAssertion(logic, expectedToBeValid);
		logic.ToArray().Should().HaveCount(logic.Count, "Count should be consistent with number of elements stored");
	}

	/// <summary>Push an integer onto <see cref="Logic"/></summary>
	protected void Push(int i) { WriteLine($"Push({i})"); Logic.Push(i); }

	/// <summary>Push a string onto <see cref="Logic"/></summary>
	protected void Push(string s) { WriteLine($"Push({s.InDoubleQuotes()})"); Logic.Push(s); }

	/// <summary>Pop a value off the top of <see cref="Logic"/></summary>
	protected object Pop()
	{
		object? value = Logic.Pop();
		if (value != null) WriteLine($"Pop() => {value} [{value.GetType()}]"); else WriteLine($"Pop() => NULL");
		return value!;
	}

	/// <summary>Pop an integer off the top of <see cref="Logic"/></summary>
	protected int Pop_int() { object value = Pop(); value.Should().NotBeNull().And.BeOfType<int>(); return (int)value; }

	/// <summary>Pop a string off the top of <see cref="Logic"/></summary>
	protected string Pop_string() { object value = Pop(); value.Should().NotBeNull().And.BeOfType<string>(); return (string)value; }

	/// <summary>Assert the content of <see cref="Logic"/> to consist of the given array of integers</summary>
	/// <param name="expected"></param>
	protected void Assert_int_content(params int[] expected)
	{
		var content = Logic.ToArray();
		WriteLine($"Logic  =  [{content.JoinValues(", ")}]");
		content.Should().AllBeOfType<int>("because the entire content of the stack is expected to be only integers");
		WriteLine($"Expected: [{expected.Reverse().JoinValues(", ")}]");
		content.Should().BeEquivalentTo(expected, "because this exact list of integer values is to be the content of the stack");
	}
}

[Trait("Logic", nameof(System.Collections.Stack))]
public class EmptyStack(ITestOutputHelper context) : StackTest(context)
{
	[Fact] public void Is_empty() { Logic.Count.Should().Be(0); Assert_int_content(); }

	[Fact] public void Under_pop() { Assert.Throws<InvalidOperationException>(Pop); }

	[Theory][InlineData(-1)][InlineData(0)][InlineData(42)]
	public void Push_int(int i) { Push(i); Logic.Count.Should().Be(1); Assert_int_content(i); }
}

[Trait("Logic", nameof(System.Collections.Stack))]
public class IntegerStack(ITestOutputHelper context) : StackTest(context)
{
	protected override void LogicInstanceInitialize() {  Push(1); Push(2); Push(3); Push(4); }

	[Fact] public void Pop_one() { Pop_int().Should().Be(4); Assert_int_content(1, 2, 3); }

	[Theory][InlineData(-1)][InlineData(0)][InlineData(42)]
	public void Push_int(int i) { Push(i); Logic.Count.Should().Be(5); Assert_int_content(1,2,3,4,i); }
}

If this is not how you prefer to write your unit tests, that's fine. Please just don't use this package then.

Quite a number of my existing test fixtures that I need to move into multitargeted xunit.v3 based NuGet package projects consist of classes deriving from any of the above mentioned TestBase base classes, so it makes it easy for me to move those over with as little change as needed.

Download

This library is available as a NuGet package on https://nuget.org. To install it, use the following command-line:

dotnet add package peSHIr.XUnit

License and Versioning

This library is licensed under the MIT License - please see the LICENSE file for details - and makes use of Semantic Versioning to try and give meaning to the version numbers, at least for the non-prereleased stuff.

Credits

This library wouldn't have been possible without the following:

Show your appreciation for my work

If you like what you see/use you could try one of these links to let me know:

You may also like

Product 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. 
.NET Framework net472 is compatible.  net48 was computed.  net481 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.0.1 110 4/21/2026

Initial release based on https://bsky.app/profile/peshir.nl/post/3mjy7ts3msc26, but with the correct (current) peSHIr.Core v1.0.6 package referencee.