Design and implement robust F# unit, property, and integration tests
Copy the install command and let the AI configure it · recommended for beginners
Please install the "fsharp-testing" skill from askskill: 1. Download https://raw.githubusercontent.com/affaan-m/ECC/main/skills/fsharp-testing/SKILL.md 2. Save it as ~/.claude/skills/fsharp-testing/SKILL.md 3. Reload skills and tell me it's ready
Generate unit tests for this F# module using xUnit, FsUnit, and Unquote. Cover normal inputs, edge cases, and exception branches, and explain the purpose of each test type.
A well-structured set of F# unit tests with notes on coverage strategy.
Design FsCheck property-based tests for this F# function. Identify useful invariants, input generation strategies, and counterexample scenarios that may reveal defects.
Runnable property-based test examples with explanations of how each property improves correctness.
Design a testing organization plan for a mid-sized F# project, including unit tests, integration tests, naming conventions, folder structure, and ways to isolate external dependencies.
A testing architecture recommendation covering project structure, conventions, and integration test approach.
Comprehensive testing patterns for F# applications using xUnit, FsUnit, Unquote, FsCheck, and modern .NET testing practices.
| Tool | Purpose |
|---|---|
| xUnit | Test framework (standard .NET ecosystem choice) |
| FsUnit.xUnit | F#-friendly assertion syntax for xUnit |
| Unquote | Assertion library using F# quotations for clear failure messages |
| FsCheck.xUnit | Property-based testing integrated with xUnit |
| NSubstitute | Mocking .NET dependencies |
| Testcontainers | Real infrastructure in integration tests |
| WebApplicationFactory | ASP.NET Core integration tests |
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 @>)
Unquote uses F# quotations so failure messages show the full expression that failed, not just "expected X got Y".
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 @>
[<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 @>
}
[<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("[email protected]", true)>]
[<InlineData("[email protected]", true)>]
let ``IsValidEmail returns expected result`` (email: string, expected: bool) =
test <@ EmailValidator.isValid email = expected @>
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
…
Conduct multi-source web research and produce cited, source-attributed reports.
Unify multi-channel notifications for routing, deduplication, escalation, and inbox consolidation.
Audit, plan, and implement SEO improvements for better search visibility.
Refine retrieved context iteratively to improve subagent understanding and output quality.
Fetches up-to-date framework docs for setup, APIs, and code examples.
Design adaptive agent workflows with eval gates and reusable skill extraction.
Learn Rust testing patterns and TDD to improve code quality and reliability.
Build high-quality Kotlin tests with Kotest, MockK, coroutines, and coverage.
Write idiomatic Go tests, benchmarks, fuzz tests, and improve coverage.
Run, filter, and debug unit tests in the VS Code repository.
Get idiomatic C# and .NET guidance for architecture, async, and dependency injection.
Design test strategies and plans with coverage, methods, and quality priorities.