Agent skill

Fsharp Testing

by affaan-m in affaan-m/ECC

F testing patterns with xUnit, FsUnit, Unquote, FsCheck property-based testing, integration tests, and test organization best practices.

MITAuto-check passedTesting & QA

Install Fsharp Testing

skills CLI
$ npx skills add affaan-m/ECC --skill fsharp-testing -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install affaan-m/ECC fsharp-testing --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/affaan-m/ECC.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/fsharp-testing .claude/skills/fsharp-testing && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
fsharp-testing
GitHub stars
274k
Used in
1 other repo
Token cost
~2k tokens
SKILL.md length
238 words
Files
1
Skills in repo
657
Repo updated
First seen
Licence
MIT

At a glance

F testing patterns with xUnit, FsUnit, Unquote, FsCheck property-based testing, integration tests, and test organization best practices.

  • Writing F tests with xUnit
  • SKILL.md covers When to Activate, Test Framework Stack, Unit Tests with xUnit + FsUnit and Property-Based Testing with…, plus 6 more sections
  • Calls dotnet
  • Tasks that involve Unit testing

What it does

Fsharp Testing is an agent skill from affaan-m/ECC. F testing patterns with xUnit, FsUnit, Unquote, FsCheck property-based testing, integration tests, and test organization best practices. Use when writing F tests with xUnit, FsUnit, Unquote, or FsCheck.

Its SKILL.md is about 2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Testing & QA, covering Unit testing, Integration testing and Test strategy. It works with .NET. The repository describes itself as: The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond. The licence is MIT.

When your agent uses it

  • Writing F tests with xUnit
  • Tasks that involve Unit testing
  • Tasks that involve Integration testing

Example prompts

  • “/fsharp-testing”

What it can do on your machine

Read from SKILL.md and the folder at commit ef648e0. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • dotnet

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Fsharp Testing loads about 2k tokens when it runs. Until then it costs about 55 tokens; SKILL.md has 238 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~55
When it runs · the whole SKILL.md, loaded when a task matches
~2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from affaan-m/ECC at commit ef648e0, republished under its MIT licence (© affaan-m). 238 words, ~1,986 tokens.

Download SKILL.mdSave it as .claude/skills/fsharp-testing/SKILL.md (or your agent's skills folder).
name
fsharp-testing
description
F# testing patterns with xUnit, FsUnit, Unquote, FsCheck property-based testing, integration tests, and test organization best practices. Use when writing F# tests with xUnit, FsUnit, Unquote, or FsCheck.
metadata.origin
ECC

F# Testing Patterns

Comprehensive testing patterns for F# applications using xUnit, FsUnit, Unquote, FsCheck, and modern .NET testing practices.

When to Activate

  • Writing new tests for F# code
  • Reviewing test quality and coverage
  • Setting up test infrastructure for F# projects
  • Debugging flaky or slow tests

Test Framework Stack

ToolPurpose
xUnitTest framework (standard .NET ecosystem choice)
FsUnit.xUnitF#-friendly assertion syntax for xUnit
UnquoteAssertion library using F# quotations for clear failure messages
FsCheck.xUnitProperty-based testing integrated with xUnit
NSubstituteMocking .NET dependencies
TestcontainersReal infrastructure in integration tests
WebApplicationFactoryASP.NET Core integration tests

Unit Tests with xUnit + FsUnit

Basic Test Structure
fsharp
module OrderServiceTests

open Xunit
open FsUnit.Xunit

[<Fact>]
let ``create sets status to Pending`` () =
    let order = Order.create "cust-1" [ validItem ]
    order.Status |> should equal Pending

[<Fact>]
let ``confirm changes status to Confirmed`` () =
    let order = Order.create "cust-1" [ validItem ]
    let confirmed = Order.confirm order
    confirmed.Status |> should be (ofCase <@ Confirmed @>)
Assertions with Unquote

Unquote uses F# quotations so failure messages show the full expression that failed, not just "expected X got Y".

fsharp
module OrderValidationTests

open Xunit
open Swensen.Unquote

[<Fact>]
let ``PlaceOrder returns success when request is valid`` () =
    let request = { CustomerId = "cust-123"; Items = [ validItem ] }
    let result = OrderService.placeOrder request
    test <@ Result.isOk result @>

[<Fact>]
let ``order total sums item prices`` () =
    let items = [ { Sku = "A"; Quantity = 2; Price = 10m }
                  { Sku = "B"; Quantity = 1; Price = 5m } ]
    let total = Order.calculateTotal items
    test <@ total = 25m @>

[<Fact>]
let ``validated email rejects empty input`` () =
    let result = ValidatedEmail.create ""
    test <@ Result.isError result @>
Async Tests
fsharp
[<Fact>]
let ``PlaceOrder returns success when request is valid`` () = task {
    let deps = createTestDeps ()
    let request = { CustomerId = "cust-123"; Items = [ validItem ] }

    let! result = OrderService.placeOrder deps request

    test <@ Result.isOk result @>
}

[<Fact>]
let ``PlaceOrder returns error when items are empty`` () = task {
    let deps = createTestDeps ()
    let request = { CustomerId = "cust-123"; Items = [] }

    let! result = OrderService.placeOrder deps request

    test <@ Result.isError result @>
}
Parameterized Tests with Theory
fsharp
[<Theory>]
[<InlineData("")>]
[<InlineData("   ")>]
let ``PlaceOrder rejects empty customer ID`` (customerId: string) =
    let request = { CustomerId = customerId; Items = [ validItem ] }
    let result = OrderService.placeOrder request
    result |> should be (ofCase <@ Error @>)

[<Theory>]
[<InlineData("", false)>]
[<InlineData("a", false)>]
[<InlineData("user@example.com", true)>]
[<InlineData("user+tag@example.co.uk", true)>]
let ``IsValidEmail returns expected result`` (email: string, expected: bool) =
    test <@ EmailValidator.isValid email = expected @>

Property-Based Testing with FsCheck

Using FsCheck.xUnit
fsharp
open FsCheck
open FsCheck.Xunit

[<Property>]
let ``order total is always non-negative`` (items: NonEmptyList<PositiveInt * decimal>) =
    let orderItems =
        items.Get
        |> List.map (fun (qty, price) ->
            { Sku = "SKU"; Quantity = qty.Get; Price = abs price })
    let total = Order.calculateTotal orderItems
    total >= 0m

[<Property>]
let ``serialization roundtrips`` (order: Order) =
    let json = JsonSerializer.Serialize order
    let deserialized = JsonSerializer.Deserialize<Order> json
    deserialized = order
Custom Generators
fsharp
type OrderGenerators =
    static member ValidEmail () =
        gen {
            let! user = Gen.elements [ "alice"; "bob"; "carol" ]
            let! domain = Gen.elements [ "example.com"; "test.org" ]
            return $"{user}@{domain}"
        }
        |> Arb.fromGen

[<Property(Arbitrary = [| typeof<OrderGenerators> |])>]
let ``valid emails pass validation`` (email: string) =
    EmailValidator.isValid email

Mocking Dependencies

Function Stubs (Preferred)
fsharp
let createTestDeps () =
    let mutable savedOrders = []
    { FindOrder = fun id -> task { return Map.tryFind id testData }
      SaveOrder = fun order -> task { savedOrders <- order :: savedOrders }
      SendNotification = fun _ -> Task.CompletedTask }

[<Fact>]
let ``PlaceOrder saves the confirmed order`` () = task {
    let mutable saved = []
    let deps =
        { createTestDeps () with
            SaveOrder = fun order -> task { saved <- order :: saved } }

    let! _ = OrderService.placeOrder deps validRequest

    test <@ saved.Length = 1 @>
}
NSubstitute for .NET Interfaces
fsharp
open NSubstitute

[<Fact>]
let ``calls repository with correct ID`` () = task {
    let repo = Substitute.For<IOrderRepository>()
    repo.FindByIdAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
        .Returns(Task.FromResult(Some testOrder))

    let service = OrderService(repo)
    let! _ = service.GetOrder(testOrder.Id, CancellationToken.None)

    do! repo.Received(1).FindByIdAsync(testOrder.Id, Arg.Any<CancellationToken>())
}

ASP.NET Core Integration Tests

fsharp
type OrderApiTests (factory: WebApplicationFactory<Program>) =
    interface IClassFixture<WebApplicationFactory<Program>>

    let client =
        factory.WithWebHostBuilder(fun builder ->
            builder.ConfigureServices(fun services ->
                services.RemoveAll<DbContextOptions<AppDbContext>>() |> ignore
                services.AddDbContext<AppDbContext>(fun options ->
                    options.UseInMemoryDatabase("TestDb") |> ignore) |> ignore))
            .CreateClient()

    [<Fact>]
    member _.``GET order returns 404 when not found`` () = task {
        let! response = client.GetAsync($"/api/orders/{Guid.NewGuid()}")
        test <@ response.StatusCode = HttpStatusCode.NotFound @>
    }

Test Organization

tests/
  MyApp.Tests/
    Unit/
      OrderServiceTests.fs
      PaymentServiceTests.fs
    Integration/
      OrderApiTests.fs
      OrderRepositoryTests.fs
    Properties/
      OrderPropertyTests.fs
    Helpers/
      TestData.fs
      TestDeps.fs

Common Anti-Patterns

Anti-PatternFix
Testing implementation detailsTest behavior and outcomes
Mutable shared test stateFresh state per test
Thread.Sleep in async testsUse Task.Delay with timeout, or polling helpers
Asserting on sprintf outputAssert on typed values and pattern matches
Ignoring CancellationTokenAlways pass and verify cancellation
Skipping property-based testsUse FsCheck for any function with clear invariants
  • dotnet-patterns - Idiomatic .NET patterns, dependency injection, and architecture
  • csharp-testing - C# testing patterns (shared infrastructure like WebApplicationFactory and Testcontainers applies to F# too)

Running Tests

bash
# Run all tests
dotnet test

# Run with coverage
dotnet test --collect:"XPlat Code Coverage"

# Run specific project
dotnet test tests/MyApp.Tests/

# Filter by test name
dotnet test --filter "FullyQualifiedName~OrderService"

# Watch mode during development
dotnet watch test --project tests/MyApp.Tests/

© affaan-m, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/fsharp-testing of affaan-m/ECC.

Open the folder on GitHubat commit ef648e0

Used in 1 other repository

We found 3 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in affaan-m/ECC, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Fsharp Testing next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Fsharp Testing compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Fsharp Testing this skillaffaan-m/ECC274k1 repos~2kAutomated safety check: PassMIT
Akka.NET Testing PatternsAaronontheweb/dotnet-skills1.2k1 repos~2.4kAutomated safety check: PassMIT
Dotnet Testingnovotnyllc/dotnet-artisan233—~972Automated safety check: PassMIT
New Event Sourceaws/aws-lambda-dotnet1.7k—~3kAutomated safety check: PassApache-2.0
Aspire Integration TestingDevBetterCom/DevBetterWeb1572 repos~2.3kAutomated safety check: PassNone
Async Test And Doc Syncdiscord-php/DiscordPHP1.1k—~3.4kAutomated safety check: NotesMIT

Similar skills

  • Akka.NET Testing Patterns

    Aaronontheweb/dotnet-skills

    Shows how to test Akka.NET actors with Akka.Hosting.TestKit: swapping services for fakes, using TestProbes, and checking persistence, plus when the older TestKit still fits.

    1.2k GitHub starsUsed in 1 repo~2.4k tokens
    Testing & QAAuto-check passed
  • Dotnet Testing

    novotnyllc/dotnet-artisan

    Defines .NET test strategy and implementation patterns across xUnit v3 (Facts, Theories, fixtures, IAsyncLifetime), integration testing (WebApplicationFactory, Testcontainers), Aspire testing…

    233 GitHub stars~972 tokensUpdated 1 mo ago
    Testing & QAAuto-check passed
  • New Event Source

    aws/aws-lambda-dotnet

    Official

    Add a new AWS event source attribute (e.g., Kinesis, Kafka, MQ) to the Lambda .NET Annotations framework, including the attribute class, source generator integration, CloudFormation writer, unit…

    1.7k GitHub stars~3k tokensUpdated yesterday
    Testing & QAAuto-check passed
  • Aspire Integration Testing

    DevBetterCom/DevBetterWeb

    Write integration tests using .NET Aspire's testing facilities with xUnit.

    157 GitHub starsUsed in 2 repos~2.3k tokens
    Testing & QAAuto-check passed
  • Async Test And Doc Sync

    discord-php/DiscordPHP

    Maintain test and documentation alignment — PHPUnit tests, async testing patterns, PHPDoc contracts, guide pages, and documentation workflow.

    1.1k GitHub stars~3.4k tokensUpdated yesterday
    Testing & QAAuto-check: notes
  • Designing Tests

    CloudAI-X/claude-workflow-v2

    Designs and implements testing strategies for any codebase. An agent skill from CloudAI-X/claude-workflow-v2.

    1.4k GitHub starsUsed in 1 repo~1.5k tokens
    Testing & QAAuto-check passed

More from affaan-m/ECC

All 657 skills in this repo
  • Skill Stocktake

    affaan-m/ECC

    Audits your installed Claude skills and commands for quality, with a quick mode for recently changed skills and a full mode that evaluates all of them through subagents.

    274k GitHub starsUsed in 5 repos~1.9k tokens
    Auto-check passed
  • Videodb

    affaan-m/ECC

    Ingest, index, search, edit, and monitor video and audio with the VideoDB Python SDK — upload from files, URLs, or RTSP feeds, build spoken and scene indexes with timestamped search and playable…

    274k GitHub starsUsed in 3 repos~3.5k tokens
    Auto-check: notes
  • Rules Distillation

    affaan-m/ECC

    Scans installed skills for principles that recur across them and proposes rule-file changes: append, revise, add a section, create a file or leave as covered.

    274k GitHub starsUsed in 2 repos~2.3k tokens
    Auto-check passed
  • Builds DRAFT counterparty agreements from one markdown template and a small JSON spec per party, with clauses picked by the party's role.

    274k GitHub stars~2.9k tokensUpdated 2 days ago
    Auto-check passed
  • Measures whether agents actually follow a skill, rule or agent definition by generating scenarios at three strictness levels and scoring tool-call traces.

    274k GitHub starsUsed in 1 repo~623 tokens
    Auto-check passed
  • Instinct-based learning system that observes sessions via hooks, creates atomic instincts with confidence scoring, and evolves them into skills/commands/agents.

    274k GitHub stars~3.5k tokensUpdated 2 days ago
    Auto-check passed

Works with

Categories

Questions about Fsharp Testing

What does Fsharp Testing do?

F testing patterns with xUnit, FsUnit, Unquote, FsCheck property-based testing, integration tests, and test organization best practices. Fsharp Testing is an agent skill from affaan-m/ECC. F testing patterns with xUnit, FsUnit, Unquote, FsCheck property-based testing, integration tests, and test organization best practices.

When should I use Fsharp Testing?

Fsharp Testing fits situations like: writing F tests with xUnit; tasks that involve Unit testing; tasks that involve Integration testing.

How do I install Fsharp Testing in Claude Code?

Run `npx skills add affaan-m/ECC --skill fsharp-testing -a claude-code`. Or copy the skill folder (skills/fsharp-testing in affaan-m/ECC) into .claude/skills/fsharp-testing in your project. Claude Code loads it when a task matches its description.

How do I install Fsharp Testing in Codex?

Run `npx skills add affaan-m/ECC --skill fsharp-testing -a codex`. Or copy the skill folder (skills/fsharp-testing in affaan-m/ECC) into .agents/skills/fsharp-testing in your project. Codex loads it when a task matches its description.

Can I use Fsharp Testing in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add affaan-m/ECC --skill fsharp-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/fsharp-testing, .gemini/skills/fsharp-testing, .github/skills/fsharp-testing and .opencode/skills/fsharp-testing in your project.

What does Fsharp Testing need to run?

Going by SKILL.md and its folder, Fsharp Testing needs the command-line tools its instructions call (dotnet).

Does Fsharp Testing access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Fsharp Testing safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Fsharp Testing use?

Fsharp Testing is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Fsharp Testing use?

About 2k tokens (SKILL.md is roughly 7.9k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Fsharp Testing?

Skills that share tags, products or a category with Fsharp Testing: Akka.NET Testing Patterns (Aaronontheweb/dotnet-skills, 1.2k stars), Dotnet Testing (novotnyllc/dotnet-artisan, 233 stars), New Event Source (aws/aws-lambda-dotnet, 1.7k stars) and Aspire Integration Testing (DevBetterCom/DevBetterWeb, 157 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Fsharp Testing?

affaan-m (a GitHub user) maintains it in affaan-m/ECC, which has 274,360 GitHub stars. The repository holds 657 skills in this directory. The repository was last updated on October 5, 2026.

Source: affaan-m/ECC on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.