Token导航 LogoToken导航

Agent Skill · 运维和基础设施

dotnet-testing-test-output-logging(dotnet 测试测试输出日志记录)

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

dotnet-testing-test-output-logging 是运维和基础设施类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描已通过,按安装量在运维和基础设施类的 2,449 个 Skill 里排第 1,383。

总安装 612周安装 26GitHub Stars 24下载 214核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

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

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --skill dotnet-testing-test-output-logging

这个 Skill 是做什么的

运维和基础设施类 Skill 处理部署、监控、日志和云资源,多数需要较高的执行权限。

协助在 .NET xUnit 项目中实现结构化测试输出记录。指导正确使用 ITestOutputHelper 进行日志写入。提供格式化输出建议,便于调试和失败分析。适用于需要详细测试过程追踪的场景,提升诊断效率。

dotnet-testing-test-output-logging 属于运维和基础设施类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/dotnet-testing-test-output-logging

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --ski…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

dotnet-testing-test-output-logging 怎么安装?

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

dotnet-testing-test-output-logging 支持哪些 AI 工具?

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

dotnet-testing-test-output-logging 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

dotnet-testing-test-output-logging 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

dotnet-testing-test-output-logging 用的人多吗?

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

dotnet-testing-test-output-logging 安全吗?

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

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

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理运维和基础设施类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

运维和基础设施类 Skill 对比

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

头脑风暴 · Codex、Claude

3,148,776173,131操作浏览器MIT通过
copywriting

文案写作 · Codex、Claude

1,996,72425,583需要联网MIT通过
openclaw-secure-linux-cloud

OpenClaw secure linux cloud 命令行 · Codex、Claude

1,853,08840接触敏感数据未明确未通过
xget

xget 命令行 · Codex、Claude

1,799,28040执行命令未明确未通过
requesting-code-review

代码审查请求 · Codex、Claude

1,590,144173,103权限未标注MIT通过
dotnet-testing-test-output-logging

dotnet 测试测试输出日志记录 · 本页

61224需要联网MIT通过

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

SKILL.md 原文

測試輸出與記錄專家指南

本技能協助您在.NET xUnit 測試專案中實作高品質的測試輸出與記錄機制。

核心原則

1. ITestOutputHelper 使用原則

正確的注入方式

  • 透過建構式注入 ITestOutputHelper
  • 每個測試類別的實例與測試方法綁定
  • 不可在靜態方法或跨測試方法間共用
public class MyTests
{
    private readonly ITestOutputHelper _output;

    public MyTests(ITestOutputHelper testOutputHelper)
    {
        _output = testOutputHelper;
    }
}

常見錯誤

  • 靜態存取:private static ITestOutputHelper _output
  • 在非同步測試中未等待即使用
  • 嘗試在 Dispose 方法中使用

2. 結構化輸出格式設計

建議的輸出結構

private void LogSection(string title)
{
    _output.WriteLine($"\n=== {title} ===");
}

private void LogKeyValue(string key, object value)
{
    _output.WriteLine($"{key}: {value}");
}

private void LogTimestamp(DateTime time)
{
    _output.WriteLine($"執行時間: {time:yyyy-MM-dd HH:mm:ss.fff}");
}

輸出時機

  • 測試開始時:記錄測試設置與輸入資料
  • 執行過程中:記錄重要的狀態變化
  • 斷言前:記錄預期值與實際值
  • 測試結束時:記錄執行時間與結果摘要

3. ILogger 測試策略

挑戰:擴充方法無法直接 Mock

ILogger.LogError() 是擴充方法,NSubstitute 無法直接攔截。需要攔截底層的 Log<TState> 方法:

// ❌ 錯誤:直接 Mock 擴充方法會失敗
logger.Received().LogError(Arg.Any<string>());

// ✅ 正確:攔截底層方法
logger.Received().Log(
    LogLevel.Error,
    Arg.Any<EventId>(),
    Arg.Is<object>(o => o.ToString().Contains("預期訊息")),
    Arg.Any<Exception>(),
    Arg.Any<Func<object, Exception, string>>()
);

解決方案:使用抽象層

建立 AbstractLogger<T> 來簡化測試:

public abstract class AbstractLogger<T> : ILogger<T>
{
    public IDisposable BeginScope<TState>(TState state)
        => null;

    public bool IsEnabled(LogLevel logLevel)
        => true;

    public void Log<TState>(
        LogLevel logLevel,
        EventId eventId,
        TState state,
        Exception exception,
        Func<TState, Exception, string> formatter)
    {
        Log(logLevel, exception, state?.ToString() ?? string.Empty);
    }

    public abstract void Log(LogLevel logLevel, Exception ex, string information);
}

測試時使用

var logger = Substitute.For<AbstractLogger<MyService>>();
// 現在可以簡單驗證
logger.Received().Log(LogLevel.Error, Arg.Any<Exception>(), Arg.Is<string>(s => s.Contains("錯誤訊息")));

4. 診斷工具整合

XUnitLogger:將記錄導向測試輸出

public class XUnitLogger<T> : ILogger<T>
{
    private readonly ITestOutputHelper _testOutputHelper;

    public XUnitLogger(ITestOutputHelper testOutputHelper)
    {
        _testOutputHelper = testOutputHelper;
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
        Exception exception, Func<TState, Exception, string> formatter)
    {
        var message = formatter(state, exception);
        _testOutputHelper.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] [{logLevel}] [{typeof(T).Name}] {message}");
        if (exception != null)
        {
            _testOutputHelper.WriteLine($"Exception: {exception}");
        }
    }

    // 其他必要的介面實作...
}

CompositeLogger:同時支援驗證與輸出

public class CompositeLogger<T> : ILogger<T>
{
    private readonly ILogger<T>[] _loggers;

    public CompositeLogger(params ILogger<T>[] loggers)
    {
        _loggers = loggers;
    }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
        Exception exception, Func<TState, Exception, string> formatter)
    {
        foreach (var logger in _loggers)
        {
            logger.Log(logLevel, eventId, state, exception, formatter);
        }
    }

    // 其他介面實作會委派給所有內部 logger...
}

使用方式

// 同時進行行為驗證與測試輸出
var mockLogger = Substitute.For<AbstractLogger<MyService>>();
var xunitLogger = new XUnitLogger<MyService>(_output);
var compositeLogger = new CompositeLogger<MyService>(mockLogger, xunitLogger);

var service = new MyService(compositeLogger);

實作指南

效能測試中的時間點記錄

[Fact]
public async Task ProcessLargeDataSet_效能測試()
{
    // Arrange
    var stopwatch = Stopwatch.StartNew();
    var checkpoints = new List<(string Stage, TimeSpan Elapsed)>();

    _output.WriteLine("開始處理大型資料集...");

    // Act & Monitor
    await processor.LoadData(dataSet);
    checkpoints.Add(("資料載入", stopwatch.Elapsed));
    _output.WriteLine($"資料載入完成: {stopwatch.Elapsed.TotalMilliseconds:F2} ms");

    await processor.ProcessData();
    checkpoints.Add(("資料處理", stopwatch.Elapsed));
    _output.WriteLine($"資料處理完成: {stopwatch.Elapsed.TotalMilliseconds:F2} ms");

    stopwatch.Stop();

    // Assert & Report
    _output.WriteLine("\n=== 效能報告 ===");
    foreach (var (stage, elapsed) in checkpoints)
    {
        _output.WriteLine($"{stage}: {elapsed.TotalMilliseconds:F2} ms");
    }
}

診斷測試基底類別

public abstract class DiagnosticTestBase
{
    protected readonly ITestOutputHelper Output;

    protected DiagnosticTestBase(ITestOutputHelper output)
    {
        Output = output;
    }

    protected void LogTestStart(string testName)
    {
        Output.WriteLine($"\n=== {testName} ===");
        Output.WriteLine($"執行時間: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
    }

    protected void LogTestData(object data)
    {
        Output.WriteLine($"測試資料: {JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true })}");
    }

    protected void LogAssertionFailure(string field, object expected, object actual)
    {
        Output.WriteLine("\n=== 斷言失敗 ===");
        Output.WriteLine($"欄位: {field}");
        Output.WriteLine($"預期值: {expected}");
        Output.WriteLine($"實際值: {actual}");
    }
}

最佳實踐

  1. 適當使用 ITestOutputHelper

- 在複雜測試中記錄重要步驟,幫助追蹤失敗原因 - 採用一致的結構化輸出格式(章節標題、時間戳記),讓輸出易於閱讀 - 在效能測試中記錄時間點,提供量化數據

  1. Logger 測試策略

- 使用抽象層(AbstractLogger)簡化測試,因為 ILogger 擴充方法無法直接 Mock - 驗證記錄層級而非完整訊息,避免測試因訊息文字微調而失敗 - 使用 CompositeLogger 結合 Mock 與實際輸出,同時達成驗證與診斷

常見誤區

  1. 過度使用輸出 — 大量輸出會拖慢測試執行速度,且雜訊會淹沒有用資訊。只在複雜或易失敗的測試中加入輸出即可。記錄敏感資訊(密碼、金鑰)也是常見的安全風險。
  2. 硬編碼記錄驗證 — 驗證完整的記錄訊息字串容易因訊息微調而失敗,驗證呼叫次數則過度指定了內部實作。改為驗證記錄層級和關鍵字即可。
  3. 忽略生命週期 — ITestOutputHelper 的實例與測試方法綁定,在靜態方法或跨測試方法中使用會拋出例外。非同步測試中遺漏 await 也可能導致輸出遺失。

範例參考

參考 templates/ 目錄下的完整範例:

  • itestoutputhelper-example.cs - ITestOutputHelper 使用範例
  • ilogger-testing-example.cs - ILogger 測試策略範例
  • diagnostic-tools.cs - XUnitLogger 與 CompositeLogger 實作

輸出格式

  • 產生含 ITestOutputHelper 注入的測試類別
  • 提供 AbstractLogger/XUnitLogger/CompositeLogger 實作程式碼
  • 包含結構化輸出的 helper 方法
  • ILogger 驗證使用底層 Log 方法而非擴充方法

參考資源

原始文章

本技能內容提煉自「老派軟體工程師的測試修練 - 30 天挑戰」系列文章:

  • Day 08 - 測試輸出與記錄:xUnit ITestOutputHelper 與 ILogger

- 鐵人賽文章:https://ithelp.ithome.com.tw/articles/10374711 - 範例程式碼:https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day08

官方文件

相關技能

  • unit-test-fundamentals - 單元測試基礎
  • xunit-project-setup - xUnit 專案設定
  • nsubstitute-mocking - 測試替身與模擬

範例檔案

測試清單

在實作測試輸出與記錄時,確認以下檢查項目:

  • ITestOutputHelper 透過建構式正確注入
  • 使用結構化的輸出格式(章節、時間戳記)
  • Logger 測試使用抽象層或 CompositeLogger
  • 驗證記錄層級而非完整訊息
  • 效能測試包含時間點記錄
  • 沒有在輸出中洩漏敏感資訊
  • 非同步測試正確等待記錄完成
  • 測試失敗時提供足夠的診斷資訊

平台分布

Claude Code

29.61%
按下载量换算63

Gemini CLI

22.56%
按下载量换算48

Antigravity

16.9%
按下载量换算36

OpenCode

12.38%
按下载量换算26

windsurf

7.63%
按下载量换算16

github-copilot

3.24%
按下载量换算7

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills