Patterns and techniques for evaluating and improving AI agent outputs.
日本語の概要は準備中です。原文の説明を表示しています。
Specialized skill for testing FluentValidation validators. Use when you need to create tests for Validator classes, validate business rules, or test error messages. Covers complete FluentValidation.TestHelper usage, ShouldHaveValidationErrorFor, async validation, cross-field logic, etc. Keywords: validator, validation, fluentvalidation, validation testing, UserValidator, CreateOrderValidator, TestHelper, ShouldHaveValidationErrorFor, ShouldNotHaveValidationErrorFor, TestValidate, TestValidateAsync, testing validators, validating business rules
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
Source: kevintsengtw/dotnet-testing-agent-skills (MIT). Ported into dotnet-agent-harness.
This skill focuses on testing data validation logic using FluentValidation.TestHelper, covering basic validation, complex business rules, async validation, and testing best practices.
Validators are the first line of defense for applications, testing validators can:
<PackageReference Include="FluentValidation" Version="11.11.0" />
<PackageReference Include="FluentValidation.TestHelper" Version="11.11.0" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="Microsoft.Extensions.Time.Testing" Version="9.0.0" />
<PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="AwesomeAssertions" Version="9.1.0" />
using FluentValidation;
using FluentValidation.TestHelper;
using Microsoft.Extensions.Time.Testing;
using NSubstitute;
using Xunit;
using AwesomeAssertions;
This section covers 7 core testing patterns, each including validator definitions and complete test examples.
For complete code examples, see references/core-test-patterns.md
TestValidate + ShouldHaveValidationErrorFor /
ShouldNotHaveValidationErrorFor to test single field rules[Theory] + [InlineData] to test multiple invalid/valid input
combinationsMust() rules, and other multi-field related
validationsTimeProvider, using FakeTimeProvider to control time for
testing.When() for optional field validation, testing conditional trigger and
skip scenariosMustAsync + TestValidateAsync, using NSubstitute Mock for external servicespublic class UserValidatorTests
{
private readonly UserValidator _validator = new();
[Fact]
public void Validate_Blank_Username_Should_Validation_Fail()
{
var result = _validator.TestValidate(
new UserRegistrationRequest { Username = "" });
result.ShouldHaveValidationErrorFor(x => x.Username)
.WithErrorMessage("Username cannot be null or blank");
}
}
| Method | Purpose | Example |
|---|---|---|
TestValidate(model) | Execute sync validation | _validator.TestValidate(request) |
TestValidateAsync(model) | Execute async validation | await _validator.TestValidateAsync(request) |
| Method | Purpose | Example |
|---|---|---|
ShouldHaveValidationErrorFor(x => x.Property) | Assert property should have error | result.ShouldHaveValidationErrorFor(x => x.Username) |
ShouldNotHaveValidationErrorFor(x => x.Property) | Assert property should not have error | result.ShouldNotHaveValidationErrorFor(x => x.Email) |
ShouldNotHaveAnyValidationErrors() | Assert entire object has no errors | result.ShouldNotHaveAnyValidationErrors() |
| Method | Purpose | Example |
|---|---|---|
WithErrorMessage(string) | Validate error message content | .WithErrorMessage("Username cannot be empty") |
WithErrorCode(string) | Validate error code | .WithErrorCode("NOT_EMPTY") |
Method_Scenario_ExpectedResult format[Theory]
[InlineData("", "Email cannot be null or blank")]
[InlineData("invalid", "Email format is incorrect")]
[InlineData("@example.com", "Email format is incorrect")]
public void Validate_Invalid_Email_Should_Validation_Fail(string email, string expectedError)
{
var request = new UserRegistrationRequest { Email = email };
var result = _validator.TestValidate(request);
result.ShouldHaveValidationErrorFor(x => x.Email).WithErrorMessage(expectedError);
}
[Theory]
[InlineData(17, "Age must be greater than or equal to 18")]
[InlineData(121, "Age must be less than or equal to 120")]
public void Validate_Invalid_Age_Should_Validation_Fail(int age, string expectedError)
{
var request = new UserRegistrationRequest { Age = age };
var result = _validator.TestValidate(request);
result.ShouldHaveValidationErrorFor(x => x.Age).WithErrorMessage(expectedError);
}
[Fact]
public void Validate_Not_Agree_To_Terms_Should_Validation_Fail()
{
var request = new UserRegistrationRequest { AgreeToTerms = false };
var result = _validator.TestValidate(request);
result.ShouldHaveValidationErrorFor(x => x.AgreeToTerms)
.WithErrorMessage("Must agree to terms of use");
}
public static class TestDataBuilder
{
public static UserRegistrationRequest CreateValidRequest()
{
return new UserRegistrationRequest
{
Username = "testuser123",
Email = "test@example.com",
Password = "<DB_PASSWORD_PLACEHOLDER>",
ConfirmPassword = "<DB_PASSWORD_PLACEHOLDER>",
BirthDate = new DateTime(1990, 1, 1),
Age = 34,
PhoneNumber = "0912345678",
Roles = new List<string> { "User" },
AgreeToTerms = true
};
}
public static UserRegistrationRequest WithUsername(this UserRegistrationRequest request, string username)
{
request.Username = username;
return request;
}
public static UserRegistrationRequest WithEmail(this UserRegistrationRequest request, string email)
{
request.Email = email;
return request;
}
}
// Usage example
var request = TestDataBuilder.CreateValidRequest()
.WithUsername("newuser")
.WithEmail("new@example.com");
This skill can be combined with:
A: Use Mock to isolate database dependencies:
_mockUserService.IsUsernameAvailableAsync("username")
.Returns(Task.FromResult(false));
A: Use FakeTimeProvider to control time:
_fakeTimeProvider.SetUtcNow(new DateTime(2024, 1, 1));
A: Test each condition separately, ensuring complete coverage:
// Test birthday passed scenario
// Test birthday not yet arrived scenario
// Test boundary date
A: Focus on testing:
This skill provides the following template files:
templates/validator-test-template.cs: Complete validator test exampletemplates/async-validator-examples.cs: Async validation examplesThis skill content is distilled from the "Old School Software Engineer's Testing Practice - 30 Day Challenge" article series:
unit-test-fundamentals - Unit testing basicsnsubstitute-mocking - Test doubles and mockingまだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Patterns and techniques for evaluating and improving AI agent outputs.
日本語の概要は準備中です。原文の説明を表示しています。
Comprehensive AI prompt engineering safety review and improvement prompt. Analyzes prompts for safety, bias, security vulnerabilities, and effectiveness while providing detailed improvement recommendations.
日本語の概要は準備中です。原文の説明を表示しています。
Use when user requests research requiring multiple sources, comprehensive analysis, or synthesis across topics - technical research, domain knowledge gathering, market analysis, or learning about complex subjects
日本語の概要は準備中です。原文の説明を表示しています。
AI-powered wiki generation for code repositories with commands, agents, and skills
日本語の概要は準備中です。原文の説明を表示しています。
Use when building .NET 10 or C# 14 applications; when using minimal APIs, modular monolith patterns, or feature folders; when implementing HTTP resilience, Options pattern, Channels, or validation; when seeing outdated patterns like old extension method syntax
日本語の概要は準備中です。原文の説明を表示しています。
Implements accessible .NET UI. SemanticProperties, ARIA, AutomationPeer, testing per platform.
日本語の概要は準備中です。原文の説明を表示しています。