DraftSpec 0.3.0-alpha.8
See the version list below for details.
dotnet add package DraftSpec --version 0.3.0-alpha.8
NuGet\Install-Package DraftSpec -Version 0.3.0-alpha.8
<PackageReference Include="DraftSpec" Version="0.3.0-alpha.8" />
<PackageVersion Include="DraftSpec" Version="0.3.0-alpha.8" />
<PackageReference Include="DraftSpec" />
paket add DraftSpec --version 0.3.0-alpha.8
#r "nuget: DraftSpec, 0.3.0-alpha.8"
#:package DraftSpec@0.3.0-alpha.8
#addin nuget:?package=DraftSpec&version=0.3.0-alpha.8&prerelease
#tool nuget:?package=DraftSpec&version=0.3.0-alpha.8&prerelease
DraftSpec
⚠️ Alpha - Experimental, expect breaking changes
RSpec-inspired testing for .NET.
DraftSpec brings the elegant describe/it/expect syntax to .NET, filling the gap left by abandoned BDD frameworks
like NSpec. Write expressive specs as scripts or traditional test classes.
Requires .NET 8+ for CSX scripts via dotnet-script, or .NET 10+ for file-based apps.
Quick Start
1. Install dotnet-script:
dotnet tool install -g dotnet-script
2. Create a spec file (Calculator.spec.csx):
#r "nuget: DraftSpec, *"
using static DraftSpec.Dsl;
describe("Calculator", () =>
{
it("adds numbers", () =>
{
expect(1 + 1).toBe(2);
});
it("handles negatives", () =>
{
expect(-1 + -1).toBe(-2);
});
});
run();
3. Run it:
dotnet script Calculator.spec.csx
Output:
Calculator
✓ adds numbers
✓ handles negatives
2 passed
Features
Nested Contexts
describe("User", () =>
{
describe("when logged in", () =>
{
it("can view dashboard", () => { /* ... */ });
it("can update profile", () => { /* ... */ });
});
describe("when logged out", () =>
{
it("redirects to login", () => { /* ... */ });
});
});
Hooks
describe("Database", () =>
{
beforeAll(() => { /* open connection once */ });
afterAll(() => { /* close connection */ });
before(() => { /* begin transaction */ });
after(() => { /* rollback transaction */ });
it("inserts record", () => { /* ... */ });
});
Async Support
it("fetches data", async () =>
{
var result = await httpClient.GetAsync("/api/users");
expect(result.StatusCode).toBe(HttpStatusCode.OK);
});
Focus & Skip
fit("only this runs", () => { }); // Focus: only focused specs run
xit("this is skipped", () => { }); // Skip: explicitly disabled
it("this is pending"); // Pending: no body = pending
Assertions
// Equality
expect(value).toBe(expected);
expect(value).toBeNull();
expect(value).toNotBeNull();
// Numbers
expect(count).toBeGreaterThan(0);
expect(count).toBeLessThan(100);
expect(price).toBeCloseTo(19.99, 0.01);
// Strings
expect(name).toContain("Smith");
expect(email).toStartWith("user@");
expect(path).toEndWith(".txt");
// Booleans
expect(isValid).toBeTrue();
expect(isEmpty).toBeFalse();
// Collections
expect(items).toContain("apple");
expect(items).toHaveCount(3);
expect(items).toBeEmpty();
// Exceptions
expect(() => Divide(1, 0)).toThrow<DivideByZeroException>();
expect(() => SafeOperation()).toNotThrow();
CLI Tool
# Run specs
draftspec run . # Run all *.spec.csx in current directory
draftspec run ./specs # Run specs in directory
draftspec run MySpec.spec.csx # Run single file
# Output formats
draftspec run . --format json # JSON output
draftspec run . --format html -o report.html
# Watch mode
draftspec watch . # Re-run on file changes
# Parallel execution and filtering
draftspec run . --parallel # Run spec files in parallel
draftspec run . --tags unit,fast # Only run specs with these tags
draftspec run . --exclude-tags slow # Exclude specs with these tags
draftspec run . --bail # Stop on first failure
dotnet test Integration (MTP)
Run specs via dotnet test with full IDE Test Explorer support:
# Create a test project
dotnet new classlib -n MyProject.Specs
cd MyProject.Specs
dotnet add package DraftSpec.TestingPlatform
# Add spec files (*.spec.csx)
# Run tests
dotnet test
# With coverage
dotnet test --collect:"XPlat Code Coverage"
Features:
- Visual Studio / VS Code / Rider Test Explorer integration
- Click-to-navigate from test results to source
- Built-in code coverage collection
- Standard
dotnet testCI/CD integration
See MTP Integration Guide for full documentation.
Configuration File
Create a draftspec.json in your project for persistent settings:
{
"parallel": true,
"timeout": 10000,
"bail": false,
"tags": {
"include": ["unit", "fast"],
"exclude": ["slow", "integration"]
},
"reporters": ["console", "json"],
"noCache": false
}
CLI options override config file values.
MCP Server (AI Integration)
DraftSpec includes an MCP server for AI-assisted testing:
# Add to Claude Desktop, VS Code, etc.
dotnet run --project src/DraftSpec.Mcp
⚠️ Security Warning: The MCP server executes arbitrary C# code with full process privileges. See SECURITY.md for:
- Security model and trust assumptions
- Deployment recommendations
- Container isolation guidance
Tools:
| Tool | Description |
|---|---|
run_spec |
Execute spec code and return structured JSON results |
scaffold_specs |
Generate pending specs from a structured description |
parse_assertion |
Convert natural language to expect() syntax |
parse_assertion - Convert natural language assertions to DraftSpec code:
// Input
{ "naturalLanguage": "should be greater than 5", "variableName": "count" }
// Output
{ "success": true, "code": "expect(count).toBeGreaterThan(5)", "confidence": 0.95 }
Supported patterns:
"should not be null"→expect(x).toNotBeNull()"should contain 'hello'"→expect(x).toContain("hello")"should have 3 items"→expect(x).toHaveCount(3)"should throw ArgumentException"→expect(() => x).toThrow<ArgumentException>()
scaffold_specs - Generate spec scaffolds for BDD (behavior-first) or characterisation (code-first) workflows:
{
"description": "UserService",
"contexts": [
{ "description": "Create", "specs": ["creates user", "hashes password"] },
{ "description": "GetById", "specs": ["returns user when found", "returns null when not found"] }
]
}
Output:
describe("UserService", () =>
{
describe("Create", () =>
{
it("creates user");
it("hashes password");
});
describe("GetById", () =>
{
it("returns user when found");
it("returns null when not found");
});
});
Agents can scaffold specs, then fill in assertions using run_spec to verify.
Middleware & Plugins
configure(runner => runner
.WithRetry(3) // Retry failed specs
.WithTimeout(5000) // 5 second timeout
.WithParallelExecution() // Run specs in parallel
);
Documentation
- Getting Started - Installation and first spec
- DSL Reference - Complete API for describe/it/hooks
- Assertions - Full expect() API reference
- CLI Reference - Command-line options
- MTP Integration - dotnet test and IDE integration
- Configuration - Middleware and plugins
Contributing
We use a PR-based workflow with branch protection on main.
Development
# Clone and build
git clone https://github.com/juvistr/draftspec.git
cd draftspec
dotnet build
# Run tests
dotnet run --project tests/DraftSpec.Tests
# Create a branch for your changes
git checkout -b feature/your-feature
Pull Request Process
- Create a feature branch from
main - Make your changes with tests
- Push and open a PR
- CI runs automatically (build, test, pack)
- After review and approval, squash-merge to
main
Releases
Releases are triggered by pushing version tags:
git tag v0.1.0-alpha.1
git push origin v0.1.0-alpha.1
This triggers the publish workflow which:
- Builds and tests the code
- Packs NuGet packages (version from tag via MinVer)
- Publishes to nuget.org
- Creates a GitHub Release with auto-generated notes
Branch Protection (Maintainers)
Recommended settings for main:
- Require PR reviews before merging
- Require status checks (CI workflow)
- Require linear history (squash merging)
- No direct pushes to main
Status
Alpha - This is an early experiment, built in roughly a day with AI assistance. It works, but expect rough edges, missing features, and breaking changes.
If you try it and hit issues, feedback is welcome via GitHub issues.
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- DraftSpec.Formatters.Abstractions (>= 0.3.0-alpha.8)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on DraftSpec:
| Package | Downloads |
|---|---|
|
DraftSpec.Mcp
MCP server for DraftSpec - run specs from AI assistants |
|
|
DraftSpec.Scripting
Roslyn-based CSX script host for DraftSpec spec execution |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.8.1-alpha.1 | 66 | 1/4/2026 |
| 0.8.0-alpha.1 | 63 | 1/3/2026 |
| 0.7.1-alpha.1 | 63 | 1/2/2026 |
| 0.7.0-alpha.2 | 64 | 1/2/2026 |
| 0.7.0-alpha.1 | 57 | 1/1/2026 |
| 0.6.3-alpha.1 | 68 | 12/31/2025 |
| 0.6.2-alpha.1 | 65 | 12/31/2025 |
| 0.6.1-alpha.1 | 67 | 12/30/2025 |
| 0.6.0-alpha.1 | 63 | 12/30/2025 |
| 0.5.0-alpha.3 | 59 | 12/29/2025 |
| 0.5.0-alpha.2 | 58 | 12/29/2025 |
| 0.5.0-alpha.1 | 60 | 12/29/2025 |
| 0.4.0-alpha.6 | 63 | 12/29/2025 |
| 0.4.0-alpha.5 | 57 | 12/29/2025 |
| 0.4.0-alpha.4 | 63 | 12/28/2025 |
| 0.4.0-alpha.3 | 59 | 12/28/2025 |
| 0.4.0-alpha.2 | 55 | 12/28/2025 |
| 0.4.0-alpha.1 | 60 | 12/28/2025 |
| 0.3.0-alpha.8 | 66 | 12/28/2025 |