Patterns and techniques for evaluating and improving AI agent outputs.
日本語の概要は準備中です。原文の説明を表示しています。
Test Data Builder Pattern complete implementation guide. Used when using builder pattern to create maintainable test data or simplify complex object test preparation. Covers fluent interface, semantic methods, default value design, and Builder composition patterns. Keywords: test data builder, builder pattern test, test data builder, object mother, fluent interface, fluent interface, UserBuilder, ProductBuilder, .With(), .Build(), AUser(), test data preparation, complex object creation, semantic testing
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
Source: kevintsengtw/dotnet-testing-agent-skills (MIT). Ported into dotnet-agent-harness.
Test Data Builder Pattern is a Builder Pattern variant specifically designed for testing, used to create clear, maintainable, and semantically explicit test data. This pattern is especially suitable for handling complex objects with multiple attributes, making test code more readable and reducing maintenance costs.
Test Data Builder Pattern is an improved version of Object Mother Pattern, mainly solving the following problems:
Too many parameter settings, unclear test intent.
Intent is explicit, only set properties test cares about.
A standard Test Data Builder should contain:
With* method chain to set propertiesAnAdminUser(), ARegularUser())public class UserBuilder
{
// Default values: provide reasonable defaults for all properties
private string _name = "Default User";
private string _email = "default@example.com";
private int _age = 25;
private List<string> _roles = new();
private UserSettings _settings = new()
{
Theme = "Light",
Language = "en-US"
};
private bool _isActive = true;
private DateTime _createdAt = DateTime.UtcNow;
// With* methods: fluent interface to set individual properties
public UserBuilder WithName(string name)
{
_name = name;
return this;
}
public UserBuilder WithEmail(string email)
{
_email = email;
return this;
}
public UserBuilder WithAge(int age)
{
_age = age;
return this;
}
public UserBuilder WithRole(string role)
{
_roles.Add(role);
return this;
}
public UserBuilder WithRoles(params string[] roles)
{
_roles.AddRange(roles);
return this;
}
public UserBuilder IsInactive()
{
_isActive = false;
return this;
}
// Semantic default creators: provide quick creation methods for common scenarios
public static UserBuilder AUser() => new();
public static UserBuilder AnAdminUser() => new UserBuilder()
.WithRoles("Admin", "User");
public static UserBuilder ARegularUser() => new UserBuilder()
.WithRole("User");
// Build method: create final object
public User Build()
{
return new User
{
Name = _name,
Email = _email,
Age = _age,
Roles = _roles.ToArray(),
Settings = _settings,
IsActive = _isActive,
CreatedAt = _createdAt
};
}
}
```text
## Using Builder in Tests
### Single Test Scenario
```csharp
[Fact]
public void CreateUser_ValidAdminUser_ShouldCreateSuccessfully()
{
// Arrange - use Builder to create test data
var adminUser = UserBuilder
.AnAdminUser()
.WithName("John Admin")
.WithEmail("john.admin@company.com")
.WithAge(35)
.Build();
var userService = new UserService();
// Act
var result = userService.CreateUser(adminUser);
// Assert
Assert.NotNull(result);
Assert.Equal("John Admin", result.Name);
Assert.Contains("Admin", result.Roles);
}
```text
### Using with Theory
```csharp
public class UserValidationTests
{
[Theory]
[MemberData(nameof(GetUserScenarios))]
public void ValidateUser_DifferentUserScenarios_ShouldReturnCorrectValidationResult(User user, bool expected)
{
var validator = new UserValidator();
var result = validator.IsValid(user);
Assert.Equal(expected, result);
}
public static IEnumerable<object[]> GetUserScenarios()
{
// Valid user scenario
yield return new object[]
{
UserBuilder.AUser()
.WithName("Valid User")
.WithEmail("valid@example.com")
.WithAge(25)
.Build(),
true
};
// Invalid user scenario - empty name
yield return new object[]
{
UserBuilder.AUser()
.WithName("")
.Build(),
false
};
}
}
```text
## Best Practices
### 1. Provide Reasonable Default Values
Good practice: defaults make object in valid state.
### 2. Use Semantic Naming
Good practice: method names express test intent.
### 3. Composition Between Builders
Good practice: Builders can be combined.
### 4. Avoid Over-complication
Keep Builder simple, don't include complex business logic.
### 5. Unified Test Data Management
Good practice: create shared test data class.
## Comparison with Other Patterns
### Test Data Builder vs. Object Mother
| Characteristic | Test Data Builder | Object Mother |
| -------- | --------------------------- | --------------------- |
| Flexibility | Highly flexible, adjustable per test | Fixed test data |
| Readability | Fluent interface, explicit intent | Need to view method implementation |
| Maintainability | Centralized management, easy to modify | Changes affect all tests |
| Usage scenarios | Unit tests, scenario tests | Simple integration tests |
### Test Data Builder vs. AutoFixture
| Characteristic | Test Data Builder | AutoFixture |
| ---------- | ----------------------- | ------------------------- |
| Control degree | Full control over object creation | Auto-generate, lower control |
| Setup complexity | Need to manually create Builder | Almost zero setup |
| Test intent | Very explicit | Need additional explanation |
| Suitable timing | Tests needing precise control | Bulk data generation, anonymous testing |
## Practical Examples
Please refer to `templates/` directory for complete implementation examples.
## Reference Resources
### Original Articles
This skill content is extracted from "Old School Software Engineer's Testing Practice - 30 Day Challenge" series.
### Extended Reading
- **Test Data Builder Original Article**: [Test Data Builders: an alternative to the Object Mother pattern](http://www.natpryce.com/articles/000714.html) by Nat Pryce
### Related Skills
- `autofixture-basics` - Using AutoFixture to auto-generate test data
- `xunit-project-setup` - xUnit test project basic setup
- `test-naming-conventions` - Test naming conventions
## Summary
Test Data Builder Pattern is an important technique for writing maintainable tests:
- **When to use**: Test objects have multiple attributes, need to reuse test data, want to express clear intent
- **Core advantages**: Improve readability, reduce maintenance costs, enhance expressiveness
- **Notes**: Keep Builder simple, provide reasonable defaults, use semantic method names
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
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.
日本語の概要は準備中です。原文の説明を表示しています。