| name | dotnet-testing-awesome-assertions-guide |
| description | Using AwesomeAssertions for fluent and readable test assertion skill. Used when writing clear assertions, comparing objects, validating collections, handling complex comparisons. Covers Should(), BeEquivalentTo(), Contain(), ThrowAsync() and complete API.
Keywords: assertions, awesome assertions, fluent assertions, assertion, fluent assertion, Should(), Be(), BeEquivalentTo, Contain, ThrowAsync, NotBeNull, object comparison, collection validation, exception assertion, AwesomeAssertions, FluentAssertions, fluent syntax
|
| metadata | {"short-description":".NET skill guidance for dotnet-testing-awesome-assertions-guide"} |
Source: kevintsengtw/dotnet-testing-agent-skills (MIT). Ported into dotnet-agent-harness.
AwesomeAssertions Fluent Assertion Guide
This skill provides a complete guide for writing high-quality test assertions using AwesomeAssertions, covering basic
syntax, advanced techniques, and best practices.
Applicable Scenarios
Use this skill when asked to perform the following tasks:
- Write clear, highly readable test assertions
- Compare complex objects or collection contents
- Verify exception throwing and messages
- Use fluent syntax (Should/Be/Contain) for test validation
- Replace native Assert with AwesomeAssertions
About AwesomeAssertions
AwesomeAssertions is a community fork version of FluentAssertions, using Apache 2.0 license, completely free
with no commercial usage restrictions.
Core Features
- Fully Free: Apache 2.0 license, suitable for commercial projects
- Fluent Syntax: Supports natural language style method chaining
- Rich Assertions: Covers objects, collections, strings, numbers, exceptions, and various other types
- Excellent Error Messages: Provides detailed and easy-to-understand failure information
- High Performance: Optimized implementation ensures test execution efficiency
- Extensible: Supports custom Assertion methods
Relationship with FluentAssertions
AwesomeAssertions is a community fork of FluentAssertions, main differences:
| Item | FluentAssertions | AwesomeAssertions |
|---|
| License | Commercial projects require payment | Apache 2.0 (completely free) |
| Namespace | FluentAssertions | AwesomeAssertions |
| API Compatibility | Original | Highly compatible |
| Community Support | Official maintenance | Community maintenance |
Installation and Setup
NuGet Package Installation
dotnet add package AwesomeAssertions
Install-Package AwesomeAssertions
```text
```xml
<ItemGroup>
<PackageReference Include="AwesomeAssertions" Version="9.1.0" PrivateAssets="all" />
</ItemGroup>
```text
```csharp
using AwesomeAssertions;
using Xunit;
```text
---
All Assertions start with `.Should()`, combined with fluent method chaining.
| Category | Common Methods | Description |
|------|----------|------|
| **Object** | `NotBeNull()`, `BeOfType<T>()`, `BeEquivalentTo()` | Null, type, equality checks |
| **String** | `Contain()`, `StartWith()`, `MatchRegex()`, `BeEquivalentTo()` | Content, patterns, case-insensitive comparison |
| **Number** | `BeGreaterThan()`, `BeInRange()`, `BeApproximately()` | Comparison, range, floating point precision |
| **Collection** | `HaveCount()`, `Contain()`, `BeEquivalentTo()`, `AllSatisfy()` | Count, content, order, conditions |
| **Exception** | `Throw<T>()`, `NotThrow()`, `WithMessage()`, `WithInnerException()` | Exception types, messages, nested exceptions |
| **Async** | `ThrowAsync<T>()`, `CompleteWithinAsync()` | Async exceptions and completion validation |
> Full syntax examples and code please refer to [references/core-assertions-syntax.md](references/core-assertions-syntax.md)
---
Use `BeEquivalentTo()` with `options` for deep object comparison:
- **Exclude properties**: `options.Excluding(u => u.Id)` — exclude auto-generated fields
- **Dynamic exclusion**: `options.Excluding(ctx => ctx.Path.EndsWith("At"))` — exclude by pattern
- **Circular references**: `options.IgnoringCyclicReferences().WithMaxRecursionDepth(10)`
---
Create domain-specific extension methods, like `product.Should().BeValidProduct()`, and reusable exclusion extensions like `ExcludingAuditFields()`.
Refer to [templates/custom-assertions-template.cs](templates/custom-assertions-template.cs) for complete implementation.
> Full examples please refer to [references/complex-object-assertions.md](references/complex-object-assertions.md)
---
- **Large data**: First use `HaveCount()` for quick count check, then sample validation (avoid full `BeEquivalentTo`)
- **Selective comparison**: Use anonymous objects + `ExcludingMissingMembers()` to only validate key properties
```csharp
// Selective property comparison — only validate key fields
order.Should().BeEquivalentTo(new
{
CustomerId = 123,
TotalAmount = 999.99m,
Status =
}, options => options.ExcludingMissingMembers());
```text
---
Follow `Method_Scenario_ExpectedResult` pattern (e.g., `CreateUser_WithValidEmail_ShouldReturnEnabledUser`).
Add `because` string assertions to provide clear failure context:
```csharp
result.IsSuccess.Should().BeFalse();
```text
Use `AssertionScope` to collect multiple failure messages, display all problems at once:
```csharp
using (new AssertionScope())
{
user.Should().NotBeNull();
user.Id.Should().BeGreaterThan(0, );
user.Email.Should().NotBeNullOrEmpty();
}
```text
---
| Scenario | Key Technique |
|------|----------|
| API response validation | `BeEquivalentTo()` + `Including()` selective comparison |
| Database entity validation | `BeEquivalentTo()` + `Excluding()` exclude auto-generated fields |
| Event validation | Subscribe to capture events validate properties one by one |
> Full code examples please refer to [references/common-scenarios.md](references/common-scenarios.md)
---
**Reason**: May contain auto-generated fields or timestamps
**Solution**:
```csharp
// Exclude dynamic fields
actual.Should().BeEquivalentTo(expected, options => options
.Excluding(x => x.Id)
.Excluding(x => x.CreatedAt)
.Excluding(x => x.UpdatedAt)
);
```text
**Reason**: Collection order is different
**Solution**:
```csharp
// Use BeEquivalentTo ignore order
actual.Should().BeEquivalentTo(expected); // Does not check order
// Or explicitly specify need to check order
actual.Should().Equal(expected); // Checks order
```text
**Reason**: Floating point precision issues
**Solution**:
```csharp
// Use precision tolerance
actualValue.Should().BeApproximately(expectedValue, 0.001);
```text
---
Write unit tests or integration tests
Need to validate complex object structures
Compare API responses or database entities
Need clear failure messages
Establish domain-specific testing standards
Performance testing (use dedicated benchmarking tools)
Load testing (use K6, JMeter, etc.)
UI testing (use Playwright, Selenium)
---
First use `unit-test-fundamentals` to establish structure, use this skill to write assertions:
```csharp
[Fact]
public void ()
{
// Arrange - follow 3A Pattern
var calculator = new Calculator();
// Act
var result = calculator.Add(2, 3);
// Assert - use AwesomeAssertions
result.Should().Be(5);
}
```text
Use `test-naming-conventions` naming conventions, combined with this skills Testing Practice - 30 Day Challenge