hw.UnitTest
23.0.3
dotnet add package hw.UnitTest --version 23.0.3
NuGet\Install-Package hw.UnitTest -Version 23.0.3
<PackageReference Include="hw.UnitTest" Version="23.0.3" />
paket add hw.UnitTest --version 23.0.3
#r "nuget: hw.UnitTest, 23.0.3"
// Install hw.UnitTest as a Cake Addin
#addin nuget:?package=hw.UnitTest&version=23.0.3
// Install hw.UnitTest as a Cake Tool
#tool nuget:?package=hw.UnitTest&version=23.0.3
Overview
Provides some support for unit-testing. It is comapatible to nunit and MSTest although is provides some more features.
Supports:
- almost any public non-abstract class can be a test class
- supports dependencies between tests
- supports tagging tests as low-priority
- supports pending-tests file as editable code file
Restrictions:
- No gui or automatic IDE-integration available
- Startup and teardown concepts are not supported. Use constructor and dispose if required.
Getting started
- Mark classes and their methods with the attribute
UnitTest
to define them as unit test. - classes must be:
- public
- static or sealed
- have no template parameters (although their base classes may have them)
- classes can be toplevel or nested
- methods must be
- public
- non-abstract
- static or not
- without parameters and return values
- include at least
Assembly.GetExecutingAssembly().RunTests()
in Main-function of your test-executable
With default configuration when executed it will create and update a file that contains the prograss of the testrun.
The file is named Test.HW.config
and is located at working directory of test run.
It is also used as input for subsequent runs by not re-running successful tests.
To completely rerun all tests just delete it.
Features
Test Selection
The testrunner is responsible for selecting the test to execute. It is done at different stages.
- For starting it accepts a list of assemblies.
- For each assembly it searches all public classes that are marked as test.
- For each such class it searches for public methods that are marked as test.
- For any such method it checks if all run-conditions are met (see below)
Run-conditions are:
- Test is not marked as sussessful by
Test.HW.config
- All dependencies are marked as successful
- Test has correct priority
#Test execution
Important: Each test (on method-level) is executed in its own environment. Even for excuting methods of the same class a new class instances is created for each method.
There are the following variants for executing a test:
Default
If the class is not static then an instance of it is created (by use of the default constructor). This instance (or null for static classes) is used for invoking the the method.
By Action
Only for debug purposes this test infrastructure can be used by providing a System.Action
to test runner.
Example:
[UnitTest]
public sealed class ExampleTest
{
[UnitTest]
public void ExampleMethod()
{
"BlaBlaBla".AssertValid()
}
}
void Main()
{
...
TestRunner.RunTest(new ExampleTest().ExampleMethod);
}
By Interface ITestFixture
Your test class can implement the interface ITestFixture
.
There you have to provide a method Run which serves a the method to execute.
It gets a freshly created instance of the class and is executed with it. As in the default case.
Although the class still has to be provided with the UnitTest attribute, this can be omitted from the method in this case.
The default variant and the ITestFixture variant can be used in the same class.
Custom Test Selection
By default the methods to execute are selected by attribute UnitTest
.
This can be extended by registering test frameworks.
You should provide an class derived from IFramework and register an instance to test runner.
Here is an example (AttributedFramework is implementing IFramework):
sealed class NunitFramework : AttributedFramework<TestFixtureAttribute,TestAttribute>
{
public static readonly NunitFramework Instance = new();
}
void RegisterIt()
{
TestRunner.RegisteredFrameworks.Add(NunitFramework.Instance);
}
The registration should take place before running any test.
The above example registers all tests from the ever-famous NUnit test suite.
To implement even more advanced test selection you can implement the IFramework
-interface.
Look at the source code if you need to achieve this. It should be easy.
Dependencies
You may derive your test class from class DependenceProvider
.
DependenceProvider
is an abstract class derived from System.Attribute
.
Thus you can use your test class as attribute. When you use this attributes on other test classes you definded a dependency.
TestRunner.RunTests
will use this information as run-condition (see above).
It has no effect on TestRunner.RunTest
.
Priorities
A class can be flagged with the attribute LowPriority
. In this case the tests contained in this class are only executed by TestRunner.RunTests
when all other tests are successful.
This will also prevent dependant test from beeing executed.
It has no effect on TestRunner.RunTest
.
Configuration
The testrunner can be configured. This can be done according to the following example:
TestRunner.Configuration.IsBreakEnabled = Debugger.IsAttached;
The following options are available:
IsBreakEnabled
This boolean is controlling the function Tracer.TraceBreak
of hw.Helper.Core.
SaveResults
This boolean controlls if Test.HW.config
is written each time a method is going to be executed by TestRunner.RunTests
.
It has no effect on TestRunner.RunTest
.
SkipSuccessfulMethods
This boolean controlls if Test.HW.config
is used to skip tests that have already been successful in a previous run.
Affects only TestRunner.RunTests
.
TestsFileName
This string may contain a path to a C# file.
TestRunner.RunTests
will write this file between each excution of a test-method.
This file will be a valid C#-file.
It will contain a line for each method that has not been executed successfully.
Thus it will shrink (hopefully) during test run whenever a test method executed successfully.
The file is looking like this example:
namespace hw.UnitTest;
public static class PendingTests
{
public static void Run()
{
// notrun
TestRunner.RunTest(new MyNameSpace.ExampleTestClass().TestMethod);
...
}
}
It is recommended to include this file into your C#-project.
Furthermore it is recommended to call the method PendingTests.Run
during your debug session.
This has the following very nice effects:
- You can easily watch the progress when you run the test outside the debugger
- You can easily switch to debug mode after a (partly) unsuccessful test run.
- In debug mode you are free to remove lines from this file that belong to tests fixed.
- In debug mode you are free to add lines to this file for newly created tests.
Recommended Configuration
In your executable you should call a function that is looking like the following example:
static void RunAllTests()
{
var configuration = TestRunner.Configuration;
if(Debugger.IsAttached)
{
configuration.IsBreakEnabled = true;
configuration.SkipSuccessfulMethods = true;
configuration.SaveResults = false;
hw.UnitTest.PendingTests.Run();
}
else
{
configuration.IsBreakEnabled = false;
configuration.SkipSuccessfulMethods = false;
configuration.SaveResults = true;
configuration.TestsFileName = SmbFile.SourcePath.PathCombine("PendingTests.cs");
Assembly.GetExecutingAssembly().RunTests();
}
}
Issues and Co.
- Report to project website on github (https://github.com/hahoyer/HWClassLibrary.cs)
- issues and feedback: https://github.com/hahoyer/HWClassLibrary.cs/issues
Learn more about Target Frameworks and .NET Standard.
-
- hw.Helper.Core (>= 23.0.6)
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 |
---|---|---|
23.0.3 | 388 | 1/19/2023 |
23.0.2 | 352 | 1/6/2023 |
23.0.1 | 273 | 1/5/2023 |
23.0.0 | 348 | 1/5/2023 |
22.0.2 | 320 | 12/16/2022 |
22.0.1 | 307 | 12/8/2022 |
22.0.0 | 537 | 2/2/2022 |
21.1.2 | 297 | 12/17/2021 |
21.1.1 | 322 | 12/7/2021 |
21.1.0 | 333 | 12/3/2021 |
21.0.0 | 276 | 11/30/2021 |
20.0.6 | 539 | 10/19/2020 |
20.0.5 | 521 | 10/7/2020 |
20.0.3 | 546 | 10/4/2020 |
20.0.2 | 539 | 10/4/2020 |
20.0.1 | 428 | 10/4/2020 |
20.0.0.3 | 494 | 10/2/2020 |
20.0.0.2 | 469 | 9/30/2020 |
20.0.0.1 | 519 | 9/30/2020 |
20.0.0 | 528 | 9/30/2020 |
17.1.0 | 1,175 | 9/26/2017 |
15.1.0 | 1,352 | 12/11/2015 |
15.0.2 | 1,294 | 4/3/2015 |
15.0.1 | 1,148 | 4/3/2015 |
15.0.0 | 1,124 | 3/31/2015 |
14.1.4 | 1,156 | 3/4/2015 |
14.1.3 | 1,163 | 10/30/2014 |
14.1.2.1 | 1,141 | 10/17/2014 |
14.1.2.1-alpha | 931 | 10/17/2014 |
14.1.2-alpha | 893 | 10/17/2014 |
14.1.1-alpha | 921 | 10/17/2014 |
14.1.0-alpha | 975 | 10/17/2014 |
14.0.0 | 1,271 | 1/14/2014 |
0.2.2-alpha | 937 | 10/18/2013 |
0.2.1-alpha | 940 | 9/16/2013 |
0.2.0-alpha | 938 | 9/15/2013 |
0.1.0 | 1,272 | 9/15/2013 |
admin: Fix for use with .net6
23.0.2
Readme added
22.0.2
admin: dependency fixed
refactor: Upgrade C#
22.0.1
Wrong version of dependency
22.0
refactor: escalating statements of deprecation
refactor: upgrade C#
21.1.2
change: IsSuccessful for methods introduced
change: PendingTests: No line is generated under error tag for successful methods
refactor: upgrade C#
21.1.1
refactor: warnings fixed
21.1
refactor: escalating statements of deprecation
21.0
refactor: Upgrade C#
20.0.6
bug: Static test methods are disabled
20.0.5
change: Trace improved
change: TestRunner configuration
20.0.4
new: Sample test file generation improved
20.0.3
new: TextPart/TextPosition
20.0.2
new: Support generation of a cs file with sample tests
20.0.0.3
new: IsBreakDisabled: debug is more convenient
Upgrade: new style
17.1
Upgrade: File to SmbFile
15.1
Use Breaking changes of hw.Helper.Core
15.0.2
New: Ability to register other test frameworks
15.0.1
Change: Test runner returns false when any test has failed
15.0
Breaking Change: Attributes TestFixture and Test renamed to UnitTest