Linkoid.SmiteUnit.Injection 0.3.2-alpha.0

This is a prerelease version of Linkoid.SmiteUnit.Injection.
dotnet add package Linkoid.SmiteUnit.Injection --version 0.3.2-alpha.0                
NuGet\Install-Package Linkoid.SmiteUnit.Injection -Version 0.3.2-alpha.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="Linkoid.SmiteUnit.Injection" Version="0.3.2-alpha.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Linkoid.SmiteUnit.Injection --version 0.3.2-alpha.0                
#r "nuget: Linkoid.SmiteUnit.Injection, 0.3.2-alpha.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.
// Install Linkoid.SmiteUnit.Injection as a Cake Addin
#addin nuget:?package=Linkoid.SmiteUnit.Injection&version=0.3.2-alpha.0&prerelease

// Install Linkoid.SmiteUnit.Injection as a Cake Tool
#tool nuget:?package=Linkoid.SmiteUnit.Injection&version=0.3.2-alpha.0&prerelease                

SmiteUnit <img src="logo.svg" align="right" width="100">

The Subprocess Method Injection Test Framework

What is SmiteUnit?

SmiteUnit is a unit-testing framework for use in environments where a traditional unit-testing framework cannot be used. Common use cases include:

  • Testing plugins for applications
  • Testing mods for video games
  • Running automated integration tests

Unique Features of SmiteUnit

1. Test Injection

  • Traditional unit-tests run portions of a program in a seperate test program. SmiteUnit differs by injecting tests into a program instead.
  • Defined injection points dictate when tests start and stop, providing a high level of control over when and where tests run within a program.
  • SmiteUnit executes the program and the injected tests in a subprocess, capturing the standard error and standard output.

2. Flexibility

  • SmiteUnit treats the target program as a black box. The original program does not need to be modified extensively to inject SmiteUnit tests.
  • Test writers have complete control over where injection points are placed, along with many other specifics about how tests are injected into the program.

3. Compatibility with Other Frameworks

  • SmiteUnit is designed to work well alongside other testing frameworks.
  • Attribute names are prefixed with "Smite" to avoid ambiguity with other attrubutes.
  • A SmiteProcess can be created to run specific tests inside a unit test written with a different framework. This is useful when validating I/O.

Packages

Name Description Latest Version
Linkoid.SmiteUnit A bundle that includes all important packages for using SmiteUnit except SmiteUnit.Injection. NuGet Version
Linkoid.SmiteUnit.Framework Includes the framework for writing tests using SmiteUnit. Tests using the framework cannot be run by IDEs or other tools without the SmiteUnit.TestAdapter. NuGet Version
Linkoid.SmiteUnit.TestAdapter An adapter for SmiteUnit.Framework that allows running tests from an IDE or from the commandline with dotnet test. NuGet Version
Linkoid.SmiteUnit.Injection Includes the assembly required for injecting SmiteUnit tests into an application. NuGet Version

Usage

To start using SmiteUnit, injection points must be added to the target program, and a seperate test project should be made to hold the tests.

Adding Injection Points

Injection points need to be added to the program in which the tests must be run. To do this, the SmiteUnit.Injection package will be used. Injection points control when the tests are started and when the tests close the program. Where these injection points go will be different depending on the program, but will have a similar idea to this example:

using SmiteUnit.Injection;

public static class Program
{
    public static void Main()
    {
        // Near startup a SmiteInjection object should be created and it's EntryPoint() method called.
        // Create it with the name of the assembly that holds the tests.
        var smiteInjection = new SmiteInjection("MyTestAssembly");

        // Call the entry point methods. Tests will start running here. 
        smiteInjection.EntryPoint();

        // If the program is interactive, there is likely some sort of update loop.
        bool updateLoop = true;
        while (updateLoop) 
        {
            // Inside of this update loop, UpdatePoint should be periodically called.
            smiteInjection.UpdatePoint();
        }

        // Finally, before the program exits, ExitPoint() should be called.
        smiteInjection.ExitPoint();

        System.Environment.Exit(0);
    }
}

Creating a Test Project

Creating a test project follows similar steps to other C# testing frameworks. It is recomended to follow the steps to set up tests for a popular framework like NUnit. After setting up a test project for your IDE, open up the .csproj file, and remove references to the popular testing framework (e.g. if NUnit's instructions were followed, delete PackageReferences to NUnit) and replace them with package references to SmiteUnit. The package references in the .csproj will probably end up looking like this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
    <PackageReference Include="coverlet.collector" Version="3.1.0" GeneratePathProperty="true" />

    
    
    

    
    <PackageReference Include="Linkoid.SmiteUnit" Version="0.3.1-alpha.0" />
    
  </ItemGroup>
</Project>

Writing Tests with SmiteUnit

To start writing tests with SmiteUnit, create a new class and add a [SmiteProcess] attribue to it, then mark test methods with the [SmiteTest] attribute.

// The SmiteProcessAttribute tells the test adapter which program to start
[SmiteProcess("MyExecutable.exe", "arguments")]
public static class MySmiteTests
{
    // The SmiteSetUpAttribute marks methods that should run before any test methods
    [SmiteSetUp]
    public static void MySetUpMethod()
    {
        Console.WriteLine("Running my set up method!");
    }

    // The SmiteTestAttribute marks methods that can be run as tests
    [SmiteTest]
    public static void MyHelloWorldTest()
    {
        Console.WriteLine("Hello World!");
    }
}

Running SmiteUnit Tests

SmiteUnit does not provide any tools for running tests, but it is compatible with Microsoft.NET.Test.Sdk via the SmiteUnit.TestAdapter which is automatically included in the SmiteUnit package. Tests should be runnable from an IDE that supports Microsoft.NET.Test.Sdk, or can be run from the commandline with dotnet test.

How SmiteUnit Works

SmiteUnit works by running a test in a sub process and capturing its input and output. Somewhere in this process there is a hook that checks for a specific test that the parent process is attempting to invoke. At the injection point if a valid test is found, the test is executed and the result is reported back to the parent process. What sets this library apart from other testing frameworks is the test writer has complete control over where the injection point is. This means that if the only way your code can possibly execute properly is as an injected dependency inside of another application that perhaps doesn't even have a proper debug mode, you will still be able to run these tests in an automated fashion.

SmiteUnit is also designed to function well with other testing frameworks and it is even possible to run SmiteUnit inside of unit test Written in a different framework. This would even be the ideal use case in situations where specific input and output of the application needs to be tested for instantce standard input and standard output.

Key Design Requirements

  • SmiteUnit should be usable in any program where the SmiteUnit assembly can be loaded and executed.
  • The program in which the test is executed must be viewed as a black box.
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.
  • .NETStandard 2.1

    • No dependencies.
  • net6.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Linkoid.SmiteUnit.Injection:

Package Downloads
Linkoid.Stardew.ValleyUnit

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.3.2-alpha.0 50 9/19/2024
0.3.1-alpha.2 65 8/25/2024
0.3.1-alpha.1 71 8/21/2024
0.3.1-alpha.0 64 8/20/2024
0.3.0-alpha 63 8/9/2024