testgen 0.3.0
dotnet tool install --global testgen --version 0.3.0
dotnet new tool-manifest
dotnet tool install --local testgen --version 0.3.0
#tool dotnet:?package=testgen&version=0.3.0
nuke :add-package testgen --version 0.3.0
testgen
CLI tool for generating hash-based unit tests for C# models.
testgen eliminates repetitive boilerplate when testing hash-based constructors by generating deterministic and exhaustive test cases for all parameter combinations.
โจ Features
- Generates
[Fact]tests for all constructor combinations - Supports ladder-style test progression (one hash at a time)
- Works via CLI or JSON configuration
- Outputs
.cstest files - Designed for hash-driven domain models
๐ฆ Installation
As a global .NET tool
dotnet tool install --global testgen
Local (from src folder)
dotnet pack -c Release
dotnet tool install --global --add-source bin/Release testgen
๐ Quick Start
1. Generate config
testgen init
Creates:
testgen.json
2. Generate tests
testgen --config=testgen.json
Output:
MyModelHashTests.cs
๐ฅ CLI Usage
testgen --name=MyModel --interface=IMyModel --hash=MyModelHash --param="id:IGuid:new Guid():new DeterminedHash(id)" --param="chartId:IGuid:new Guid():new DeterminedHash(chartId)" --out=MyModelHashTests.cs
โ ๏ธ Passing Parameters via CLI
Each parameter must follow this format:
name:type:init:hashExpr
Example:
--param="id:IGuid:new Guid():new DeterminedHash(id)"
โ Important: spaces in expressions
Shell splits arguments by spaces. If your expressions contain spaces (e.g. new Guid()), you must wrap the entire parameter in quotes.
โ Correct
--param="id:IGuid:new Guid():new DeterminedHash(id)"
โ Incorrect
--param=id:IGuid:new Guid():new DeterminedHash(id)
This will be parsed incorrectly as multiple arguments.
๐ก Tip
For complex models, prefer JSON config:
testgen --config=testgen.json
It is more readable and less error-prone.
โ๏ธ Configuration
Example testgen.json:
{
"ModelName": "MyModel",
"ModelHash": "MyModelHash",
"ModelInterface": "IMyModel",
"Params": [
{
"Type": "IGuid",
"Name": "id",
"Init": "new Guid()",
"HashExpr": "new Hash(id)"
},
{
"Type": "IString",
"Name": "name",
"Init": "new String()",
"HashExpr": "new Hash(name)"
}
]
}
๐งช Generated Output
Value-based test
[Fact]
public void ProduceCorrectHashFromValues()
{
IGuid id = new Guid();
IGuid chartId = new Guid();
IMyModel model = new MyModel(
id,
chartId
);
MyModelHash expected = new MyModelHash(model);
MyModelHash actual = new MyModelHash(
id,
chartId
);
Assert.True(expected.SequenceEqual(actual));
}
Hash-based test
[Fact]
public void ProduceCorrectHashFromIdHash()
{
IGuid id = new Guid();
IGuid chartId = new Guid();
IMyModel model = new MyModel(
id,
chartId
);
MyModelHash expected = new MyModelHash(model);
MyModelHash actual = new MyModelHash(
new DeterminedHash(id),
chartId
);
Assert.True(expected.SequenceEqual(actual));
}
๐ง How It Works
For a model with N parameters, testgen:
- Builds a model using raw values
- Generates expected hash via model constructor
- Iterates through parameter combinations
- Replaces values with hashes according to mask
- Verifies equality using
SequenceEqual
Tests are sorted by number of hash parameters for better readability.
๐ Before / After
โ Manual approach
- Write dozens of repetitive tests
- Easy to miss combinations
- Hard to maintain
โ With testgen
testgen --config=testgen.json
- All combinations generated automatically
- Deterministic and consistent
- Minimal maintenance
๐ Arguments
| Argument | Description |
|---|---|
--name |
Model class name |
--hash |
Hash class name (optional) |
--interface |
Model interface (optional) |
--param |
Parameter definition (name:type:init:hashExpr, wrap in quotes if needed) |
--config |
Path to JSON config |
--out |
Output file (optional) |
--help, -h |
Show help |
๐ Examples
See /examples:
examples/
โโโ testgen.json
โโโ generated-tests.cs
๐ License
MIT License
๐ค Contributing
Contributions are welcome.
If you find a bug or want a feature โ open an issue or submit a PR.
| 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 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 is compatible. 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. |
This package has no dependencies.