Token导航 LogoToken导航

Agent Skill · 前端设计

xunit-testing-patterns(xunit 测试模式)

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

xunit-testing-patterns 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为只读;许可证信息还不明确,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 7,061。

总安装 423周安装 18GitHub Stars 21下载 148核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:xunit-testing-patterns(xunit 测试模式)
来源仓库:https://github.com/thapaliyabikendra/ai-artifacts
仓库路径:skills/xunit-testing-patterns
安装命令:
npx skills add https://github.com/thapaliyabikendra/ai-artifacts --skill xunit-testing-patterns
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/thapaliyabikendra/ai-artifacts --skill xunit-testing-patterns

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

用于辅助测试设计、自动化测试、用例整理和回归验证,适合编写单元测试或端到端测试。可生成测试计划、分析失败日志并定位问题,需结合项目测试框架使用。通过 npx skills add 命令从指定 GitHub 仓库安装使用。涉及浏览器或外部服务时,应区分本地模拟与生产环境,避免误改逻辑。

xunit-testing-patterns 属于前端设计类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/xunit-testing-patterns

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/thapaliyabikendra/ai-artifacts --skill xunit-t…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它标注为只读,先用只读任务试一次,确认行为符合预期再扩大使用范围。

常见问题

6 条

xunit-testing-patterns 怎么安装?

在终端执行 npx skills add https://github.com/thapaliyabikendra/ai-artifacts --skill xunit-testing-pat…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

xunit-testing-patterns 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

xunit-testing-patterns 需要什么权限?

权限级别是只读。该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

xunit-testing-patterns 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

xunit-testing-patterns 用的人多吗?

公开数据是累计安装 423 次,近一周安装 18 次,下载 148 次,GitHub 21 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

xunit-testing-patterns 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。
  • 标注为只读权限,试用阶段不容易误改本地文件。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。
  • 只想先试试效果、不希望它改动本地文件的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
xunit-testing-patterns

xunit 测试模式 · 本页

42321只读未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

xUnit Testing Patterns for ABP Framework

Comprehensive testing patterns for ABP Framework applications using xUnit, Shouldly, and NSubstitute.

When to Use

  • Writing unit tests for AppServices
  • Creating integration tests for ABP modules
  • Setting up test data seeders
  • Mocking repositories and services
  • Testing authorization and validation
  • Writing domain service tests
  • Interface-first testing (writing tests before implementation)

Test Project Structure

{ProjectName}.TestBase/
├── {ProjectName}TestBase.cs           # Base class with common setup
├── {ProjectName}TestBaseModule.cs     # Test module configuration
└── {Feature}/
    ├── {Entity}TestData.cs            # Test constants
    └── {Entity}TestDataSeedContributor.cs  # Test data seeder

{ProjectName}.Application.Tests/
├── {ProjectName}ApplicationTestBase.cs  # Application test base
├── {ProjectName}ApplicationTestModule.cs
└── {Feature}/
    └── {Entity}AppService_Tests.cs    # AppService tests

{ProjectName}.Domain.Tests/
├── {ProjectName}DomainTestBase.cs     # Domain test base
├── {ProjectName}DomainTestModule.cs
└── {Feature}/
    └── {Entity}Manager_Tests.cs       # Domain service tests

Interface-First Testing (NEW)

Write tests against interfaces before implementation exists. This enables parallel development in /add-feature workflow.

Benefits

  1. Tests can be written as soon as interface contracts exist
  2. Enables true parallel execution of abp-developer and qa-engineer
  3. Tests document expected behavior
  4. Catches interface design issues early

Example: Testing Against Interface

// This test compiles and is ready to run once implementation exists
public class PatientAppService_Tests : ClinicApplicationTestBase
{
    private readonly IPatientAppService _patientAppService;

    public PatientAppService_Tests()
    {
        // Resolves implementation from DI container
        _patientAppService = GetRequiredService<IPatientAppService>();
    }

    [Fact]
    public async Task GetAsync_WithValidId_ReturnsPatient()
    {
        // Arrange - uses test data constants
        var patientId = PatientTestData.Patient1Id;

        // Act - calls interface method
        var result = await _patientAppService.GetAsync(patientId);

        // Assert - validates contract expectations
        result.ShouldNotBeNull();
        result.Id.ShouldBe(patientId);
        result.FirstName.ShouldBe(PatientTestData.Patient1FirstName);
    }
}

Core Templates

Test Data Constants

// {ProjectName}.TestBase/{Feature}/{Entity}TestData.cs
namespace {ProjectName}.{Feature};

public static class PatientTestData
{
    // Use deterministic GUIDs for test reproducibility
    public static Guid Patient1Id { get; } = Guid.Parse("00000000-0000-0000-0001-000000000001");
    public static Guid Patient2Id { get; } = Guid.Parse("00000000-0000-0000-0001-000000000002");
    public static Guid NonExistentId { get; } = Guid.Parse("00000000-0000-0000-0001-999999999999");

    // Valid test data
    public const string Patient1FirstName = "John";
    public const string Patient1LastName = "Doe";
    public const string Patient1Email = "john.doe@example.com";

    public const string Patient2FirstName = "Jane";
    public const string Patient2LastName = "Smith";
    public const string Patient2Email = "jane.smith@example.com";

    // Valid data for create tests
    public const string ValidFirstName = "New";
    public const string ValidLastName = "Patient";
    public const string ValidEmail = "new.patient@example.com";

    // Invalid data for negative tests
    public const string EmptyString = "";
    public const string WhitespaceString = "   ";
    public static readonly string TooLongName = new('X', 256);
    public const string InvalidEmail = "not-an-email";
}

Test Data Seeder

// {ProjectName}.TestBase/{Feature}/{Entity}TestDataSeedContributor.cs
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;

namespace {ProjectName}.{Feature};

public class PatientTestDataSeedContributor : IDataSeedContributor, ITransientDependency
{
    private readonly IRepository<Patient, Guid> _repository;

    public PatientTestDataSeedContributor(IRepository<Patient, Guid> repository)
    {
        _repository = repository;
    }

    public async Task SeedAsync(DataSeedContext context)
    {
        // Idempotent seeding
        if (await _repository.GetCountAsync() > 0)
        {
            return;
        }

        // Patient 1 - Active
        await _repository.InsertAsync(
            new Patient(
                PatientTestData.Patient1Id,
                PatientTestData.Patient1FirstName,
                PatientTestData.Patient1LastName,
                PatientTestData.Patient1Email),
            autoSave: true);

        // Patient 2 - For deletion/update tests
        await _repository.InsertAsync(
            new Patient(
                PatientTestData.Patient2Id,
                PatientTestData.Patient2FirstName,
                PatientTestData.Patient2LastName,
                PatientTestData.Patient2Email),
            autoSave: true);
    }
}

AppService Test Class

For full test class template with all CRUD operations, lifecycle tests, and mocking patterns: See references/appservice-test-template.md

Quick example:

[Trait("Category", "Integration")]
public class {Entity}AppService_Tests : {ProjectName}ApplicationTestBase
{
    private readonly I{Entity}AppService _{entity}AppService;

    public {Entity}AppService_Tests()
    {
        _{entity}AppService = GetRequiredService<I{Entity}AppService>();
    }

    [Fact]
    public async Task GetAsync_WithValidId_Returns{Entity}()
    {
        var result = await _{entity}AppService.GetAsync({Entity}TestData.{Entity}1Id);
        result.ShouldNotBeNull();
        result.Id.ShouldBe({Entity}TestData.{Entity}1Id);
    }

    [Fact]
    public async Task CreateAsync_WithValidInput_CreatesAndReturns{Entity}()
    {
        var input = new Create{Entity}Dto { Name = {Entity}TestData.ValidName };
        var result = await _{entity}AppService.CreateAsync(input);
        result.ShouldNotBeNull();
        result.Id.ShouldNotBe(Guid.Empty);
    }
}

Test Categories

1. Happy Path Tests

Test normal successful operations.

[Fact]
public async Task Should_Create_Entity_Successfully()
{
    // Standard create with valid data
}

2. Validation Tests

Test input validation and constraints.

[Theory]
[InlineData("")]
[InlineData(null)]
[InlineData("   ")]
public async Task Should_Reject_Invalid_Name(string? name)
{
    var input = new CreateDto { Name = name! };
    await Should.ThrowAsync<AbpValidationException>(
        () => _service.CreateAsync(input));
}

3. Authorization Tests

Test permission enforcement.

[Fact]
public async Task Should_Require_Permission_To_Create()
{
    // Login as user without permission
    await WithUnitOfWorkAsync(async () =>
    {
        await Should.ThrowAsync<AbpAuthorizationException>(
            () => _service.CreateAsync(input));
    });
}

4. Edge Case Tests

Test boundary conditions and edge cases.

[Fact]
public async Task Should_Handle_Empty_List()
{
    // Clear all data
    var result = await _service.GetListAsync(new GetListInput());
    result.TotalCount.ShouldBe(0);
    result.Items.ShouldBeEmpty();
}

[Fact]
public async Task Should_Handle_Max_Page_Size()
{
    var result = await _service.GetListAsync(
        new GetListInput { MaxResultCount = 1000 });
    result.Items.Count.ShouldBeLessThanOrEqualTo(100); // Capped
}

5. Lifecycle Tests (for Activate/Deactivate patterns)

See references/appservice-test-template.md for full lifecycle test examples.

Test Traits for Organization

// Categorize tests for selective execution
[Trait("Category", "Unit")]
[Trait("Feature", "Patients")]
public class PatientAppService_UnitTests { }

[Trait("Category", "Integration")]
[Trait("Feature", "Patients")]
public class PatientAppService_IntegrationTests { }

// Run by category:
// dotnet test --filter "Category=Unit"
// dotnet test --filter "Feature=Patients"

Mocking with NSubstitute

using NSubstitute;

// Create mock
var repository = Substitute.For<IRepository<{Entity}, Guid>>();

// Setup return value
repository.GetAsync(entityId).Returns(entity);

// Verify call
await repository.Received(1).GetAsync(entityId);

For full mocking examples, see references/appservice-test-template.md.

Shouldly Assertion Patterns

// Null checks
result.ShouldNotBeNull();
result.ShouldBeNull();

// Equality
result.Id.ShouldBe(expectedId);
result.Name.ShouldNotBe(oldName);

// Collections
result.Items.ShouldNotBeEmpty();
result.Items.ShouldContain(x => x.Name == "Test");
result.Items.Count.ShouldBe(5);
result.Items.ShouldAllBe(x => x.IsActive);

// Numeric comparisons
result.TotalCount.ShouldBeGreaterThan(0);
result.TotalCount.ShouldBeLessThanOrEqualTo(100);
result.TotalCount.ShouldBeInRange(1, 100);

// String assertions
result.Name.ShouldStartWith("Test");
result.Email.ShouldContain("@");
result.Name.ShouldNotBeNullOrWhiteSpace();

// Boolean assertions
result.IsActive.ShouldBeTrue();
result.IsDeleted.ShouldBeFalse();

// Exception assertions
await Should.ThrowAsync<EntityNotFoundException>(
    async () => await _service.GetAsync(invalidId));

var ex = await Should.ThrowAsync<BusinessException>(
    async () => await _service.CreateAsync(input));
ex.Code.ShouldBe("DuplicateEmail");

Parallel Test Safety

When tests run in parallel, ensure data isolation:

// Use unique IDs per test class
public static class PatientTestData
{
    // Include feature identifier in GUIDs to avoid collisions
    private const string FeaturePrefix = "00000000-0000-0001";

    public static Guid Patient1Id { get; } = Guid.Parse($"{FeaturePrefix}-0001-000000000001");
    public static Guid Patient2Id { get; } = Guid.Parse($"{FeaturePrefix}-0001-000000000002");
}

Test Checklist

For each AppService, verify:

  • GetAsync - valid ID returns entity
  • GetAsync - non-existent ID throws EntityNotFoundException
  • GetListAsync - returns paginated results
  • GetListAsync - respects filters
  • GetListAsync - respects pagination
  • CreateAsync - valid input creates entity
  • CreateAsync - empty required field throws validation
  • CreateAsync - exceeds max length throws validation
  • UpdateAsync - valid input updates entity
  • UpdateAsync - non-existent ID throws EntityNotFoundException
  • DeleteAsync - valid ID deletes entity
  • DeleteAsync - non-existent ID throws EntityNotFoundException
  • (If applicable) ActivateAsync - activates inactive entity
  • (If applicable) DeactivateAsync - deactivates active entity

Shared Knowledge

For foundational patterns, see the shared knowledge base:

TopicFileDescription
Folder structureknowledge/conventions/folder-structure.mdTest project layout
Naming conventionsknowledge/conventions/naming.mdTest class naming
CRUD exampleknowledge/examples/crud-entity.mdTest target example

References

平台分布

Codex

36.61%
按下载量换算54

Claude

27.52%
按下载量换算41

Cursor

19.51%
按下载量换算29

Gemini CLI

8.28%
按下载量换算12

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills