Token导航 LogoToken导航TokenDH.com
研究检索操作浏览器github未标认证来源可访问许可证需确认审计通过

observability-driven-testing可观察性驱动测试

Agent Skill

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

总安装

279

周安装

12

GitHub Stars

4

下载量

98
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

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

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

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/petrkindlmann/qa-skills --skill observability-driven-testing

简介

基于可观测性数据进行测试用例设计与验证。

  • 适用于端到端测试与回归测试场景支持。
  • 使用 npx skills add 命令从 petrkindlmann/qa-skills 安装。
  • 需区分测试环境与生产环境的数据隔离机制。
  • observability-driven-testing 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

SKILL.md


Discovery Questions

Check .agents/qa-project-context.md first. If it exists, use it as context and skip questions already answered there.

Observability stack:

  • What APM/tracing tool is in place? (Datadog, New Relic, Honeycomb, Jaeger, Grafana Tempo)
  • Is OpenTelemetry instrumented in the application? Which services?
  • What logging infrastructure exists? (ELK, Loki, CloudWatch, Datadog Logs)
  • Are structured logs used, or free-form text?

Tracing maturity:

  • Are distributed traces available across service boundaries?
  • What is the trace sampling rate? (100%, 10%, head-based, tail-based)
  • Can you search traces by error status, latency threshold, or custom attributes?
  • Are traces correlated with logs and metrics?

Production error tracking:

  • What error tracking tool is used? (Sentry, Bugsnag, Rollbar, Datadog Error Tracking)
  • How are production errors triaged? (Automated, manual, ignored)
  • Is there a process for turning production errors into test cases?
  • What was the last production error that a test should have caught?

Test infrastructure:

  • Can tests emit telemetry? (Traces, custom metrics, structured logs)
  • Are test results correlated with application telemetry?
  • Do you have a test-to-code coverage mapping?

Core Principles

1. Production data informs test priorities

The most valuable tests are the ones that prevent real production errors. Not theoretical edge cases, not contrived scenarios -- real failures that real users experienced. Production error logs are a prioritized backlog of tests you should have written.

2. Traces are test evidence

A test assertion that checks "the API returned 200" proves the endpoint responded. A trace assertion that verifies "the request hit the cache, skipped the database, and returned in <50ms" proves the system behaved correctly at every layer. Traces make tests deeper without making them more brittle.

3. Observability gaps equal test gaps

If a code path has no traces, no logs, and no metrics, it is invisible. Invisible code is untestable in production and unverifiable during incidents. Observability coverage and test coverage are two views of the same problem.

4. Close the feedback loop

The complete cycle: production error detected, error analyzed, test written, test deployed, error prevented from recurring. If your team finds production errors but does not systematically create tests, the same class of error will recur.


Traces as Test Evidence

OpenTelemetry integration in test infrastructure

Instrument your test runner to emit traces that correlate test execution with application behavior.

// test-setup/tracing.ts
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { Resource } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';

const sdk = new NodeSDK({
  resource: new Resource({
    [ATTR_SERVICE_NAME]: 'integration-tests',
    'test.suite': process.env.TEST_SUITE_NAME ?? 'unknown',
    'test.run_id': process.env.CI_RUN_ID ?? `local-${Date.now()}`,
  }),
  traceExporter: new OTLPTraceExporter({
    url: process.env.OTEL_EXPORTER_ENDPOINT ?? 'http://localhost:4318/v1/traces',
  }),
});

sdk.start();

// Shutdown gracefully after tests
process.on('beforeExit', () => sdk.shutdown());

Trace-based assertions

Assert on trace structure, span attributes, and timing -- not just HTTP responses.

import { expect } from '@playwright/test';
import { TraceCollector } from './trace-collector';

test('order creation produces correct trace structure', async ({ request }) => {
  const collector = new TraceCollector();
  const traceId = crypto.randomUUID().replace(/-/g, '');

  // Make request with trace context
  const response = await request.post('/api/orders', {
    data: { items: [{ sku: 'WIDGET-1', quantity: 2 }] },
    headers: { 'traceparent': `00-${traceId}-${crypto.randomUUID().replace(/-/g, '').slice(0, 16)}-01` },
  });
  expect(response.ok()).toBeTruthy();

  // Wait for trace to propagate (async collection)
  const trace = await collector.waitForTrace(traceId, { timeout: 10_000 });

  // Assert on trace structure
  const spans = trace.spans;

  // Verify the expected service calls happened
  const serviceNames = spans.map(s => s.resource['service.name']);
  expect(serviceNames).toContain('api-gateway');
  expect(serviceNames).toContain('order-service');
  expect(serviceNames).toContain('inventory-service');

  // Verify no unexpected errors in any span
  const errorSpans = spans.filter(s => s.status?.code === 'ERROR');
  expect(errorSpans).toHaveLength(0);

  // Verify latency requirements
  const rootSpan = spans.find(s => !s.parentSpanId);
  expect(rootSpan!.durationMs).toBeLessThan(500);

  // Verify correct database operations
  const dbSpans = spans.filter(s => s.attributes['db.system'] !== undefined);
  expect(dbSpans.some(s => s.attributes['db.operation'] === 'INSERT')).toBeTruthy();
  expect(dbSpans.some(s => s.attributes['db.statement']?.toString().includes('orders'))).toBeTruthy();
});

Distributed trace validation across services

For microservices, verify that requests flow through the expected services in the correct order.

// Trace structure assertion helper
interface ExpectedSpan {
  service: string;
  operation: string;
  attributes?: Record<string, string | number>;
  maxDuration?: number;
}

async function assertTraceStructure(
  traceId: string,
  expected: ExpectedSpan[],
  collector: TraceCollector,
): Promise<void> {
  const trace = await collector.waitForTrace(traceId, { timeout: 15_000 });

  for (const exp of expected) {
    const matching = trace.spans.find(
      s => s.resource['service.name'] === exp.service && s.name === exp.operation,
    );

    expect(matching, `Expected span: ${exp.service}/${exp.operation}`).toBeDefined();

    if (exp.attributes) {
      for (const [key, value] of Object.entries(exp.attributes)) {
        expect(matching!.attributes[key]).toBe(value);
      }
    }

    if (exp.maxDuration) {
      expect(matching!.durationMs).toBeLessThan(exp.maxDuration);
    }
  }
}

// Usage
test('checkout flow traverses expected services', async ({ request }) => {
  const traceId = generateTraceId();
  await request.post('/api/checkout', {
    headers: { traceparent: formatTraceparent(traceId) },
    data: { cartId: 'test-cart-123' },
  });

  await assertTraceStructure(traceId, [
    { service: 'api-gateway', operation: 'POST /api/checkout' },
    { service: 'cart-service', operation: 'getCart', maxDuration: 100 },
    { service: 'pricing-service', operation: 'calculateTotal', maxDuration: 200 },
    { service: 'payment-service', operation: 'processPayment', attributes: { 'payment.provider': 'stripe' } },
    { service: 'order-service', operation: 'createOrder' },
    { service: 'notification-service', operation: 'sendConfirmation' },
  ], collector);
});

Log-Informed Test Design

Analyze production error logs for test gaps

Production errors are the highest-priority input for test creation. Each unhandled error represents a missing test.

// Script: analyze-production-errors.ts
// Run weekly to identify test gaps from production error data

interface ProductionError {
  message: string;
  stack: string;
  count: number;
  firstSeen: string;
  lastSeen: string;
  endpoint: string;
  userId?: string;
}

interface TestGap {
  error: ProductionError;
  coveredByTest: boolean;
  suggestedTestType: 'unit' | 'integration' | 'e2e';
  priority: 'critical' | 'high' | 'medium' | 'low';
}

function analyzeTestGaps(
  errors: ProductionError[],
  testCoverage: Map<string, string[]>, // endpoint -> test file paths
): TestGap[] {
  return errors.map(error => {
    const testsForEndpoint = testCoverage.get(error.endpoint) ?? [];
    const coveredByTest = testsForEndpoint.length > 0;

    // Prioritize by frequency and recency
    const daysSinceLastSeen = daysBetween(new Date(error.lastSeen), new Date());
    const priority = error.count > 100 && daysSinceLastSeen < 7 ? 'critical'
      : error.count > 50 ? 'high'
      : error.count > 10 ? 'medium'
      : 'low';

    // Suggest test type based on error characteristics
    const suggestedTestType = error.stack.includes('TypeError') ? 'unit'
      : error.stack.includes('timeout') || error.stack.includes('ECONNREFUSED') ? 'integration'
      : 'e2e';

    return { error, coveredByTest, suggestedTestType, priority };
  });
}

Categorize errors: covered vs. uncovered

Error categorization workflow:

1. Export production errors from error tracker (Sentry, Bugsnag, etc.)
   - Filter: last 30 days, count > 5 (ignore one-off errors)
   - Group by: error message fingerprint

2. For each error group:
   a. Does a test exist that would catch this error?
      → Yes: the test is either not running or has a gap (investigate)
      → No: this is a test gap (create a test)

   b. What layer should the test live at?
      → TypeError, null reference → unit test
      → Timeout, connection error → integration test with fault injection
      → UI rendering error → E2E test
      → Data inconsistency → contract test or database test

3. Output: prioritized list of tests to create, ordered by:
   error frequency × user impact × recency

Prioritize test creation by error frequency and impact

Prioritize using a 2x2 matrix of frequency (high/low) vs. impact (high/low): P0 = high-frequency + high-impact (fix now), P1 = low-frequency + high-impact (next sprint), P2 = high-frequency + low-impact (this sprint), P3 = both low (backlog). Impact indicators: high = payment/auth failure, data loss, crash; low = UI glitch, slow but functional response.


Telemetry-Driven Test Prioritization

Use real usage data to weight test importance

Not all features are equally used. Invest test effort proportionally to real usage. Score each endpoint by: (requests_per_day / 1000) * (1 + error_rate * 100) / max(test_count, 1). High traffic + high error rate + low test count = highest priority for new tests.

Hot path analysis

Identify the most-traversed code paths in production and ensure they have proportional test coverage.

Hot path analysis process:

1. Extract top 20 endpoints by request volume from APM data
2. For each endpoint, trace the code path through services
3. Map each service-level span to test coverage data
4. Identify hot paths with zero or low test coverage

Output:
  /api/checkout → cart-service → pricing-service → payment-service
  Coverage: cart-service (82%) → pricing-service (45%) → payment-service (91%)
  Gap: pricing-service discount calculation has 45% coverage on a critical path
  Action: Add tests for discount edge cases in pricing-service

Error rate by endpoint to test coverage mapping

Endpoint error-coverage matrix:

Endpoint           | Requests/day | Error Rate | Test Count | Gap Score
POST /api/orders   | 50,000       | 0.3%       | 2          | CRITICAL
GET  /api/search   | 200,000      | 0.05%      | 15         | OK
POST /api/auth     | 80,000       | 0.1%       | 8          | OK
PUT  /api/profile  | 5,000        | 1.2%       | 1          | HIGH
DELETE /api/items   | 2,000        | 0.8%       | 0          | HIGH

Gap Score = (error_rate × requests_per_day) / max(test_count, 1)

Action: Create tests for endpoints with Gap Score > threshold

Production Error to Test Pipeline

The most important workflow in this skill: turning production errors into tests that prevent recurrence.

Step-by-step pipeline

1. ERROR DETECTED
   Source: Sentry, Datadog, CloudWatch, or any error tracker
   Capture: error message, stack trace, request context, trace ID, user impact

2. REPRODUCE
   - Pull the trace from the observability platform
   - Identify the exact request parameters and state that triggered the error
   - Reproduce locally or in staging with equivalent input
   - If not reproducible: add targeted logging and wait for recurrence

3. WRITE TEST
   - Choose the right test layer (unit for logic bugs, integration for service interactions)
   - Test must fail before the fix is applied (red-green verification)
   - Include the production context in the test name or comment

4. FIX AND DEPLOY
   - Fix the bug
   - Verify the test passes with the fix
   - Deploy fix + test together

5. VERIFY ELIMINATION
   - Monitor the same error in production after deploy
   - Confirm error count drops to zero
   - If error recurs: the fix was incomplete, repeat from step 2

Implementation example

// Test created from production error: Sentry issue PROJ-4521
// Error: "Cannot read properties of null (reading 'address')"
// Context: POST /api/orders when user has no shipping address saved
// Frequency: 47 occurrences in last 7 days

describe('order creation with missing shipping address', () => {
  // This test was created because production error PROJ-4521 showed that
  // users without a saved shipping address triggered a null reference error
  // in the order validation pipeline.

  it('returns 400 with clear error message when shipping address is null', async () => {
    const user = await createTestUser({ address: null });
    const response = await api.post('/api/orders', {
      userId: user.id,
      items: [{ sku: 'WIDGET-1', quantity: 1 }],
    });

    expect(response.status).toBe(400);
    expect(response.body.error).toBe('MISSING_SHIPPING_ADDRESS');
    expect(response.body.message).toContain('shipping address is required');
  });

  it('prompts user to add address when attempting checkout without one', async ({ page }) => {
    await loginAs(page, { address: null });
    await page.goto('/checkout');
    await expect(page.getByText('Please add a shipping address')).toBeVisible();
    await expect(page.getByRole('link', { name: 'Add address' })).toBeVisible();
  });
});

Diagnosis Workflows

Trace a failing request end-to-end

When a test fails or a production error occurs, use the trace to understand exactly what happened.

Diagnosis flow:

1. Get the trace ID (from test output, error tracker, or user report)

2. Open the trace in your APM tool
   - Jaeger: /trace/{traceId}
   - Datadog: /apm/traces?traceId={traceId}
   - Honeycomb: query by trace.trace_id

3. Walk the span tree
   - Root span: what did the user request?
   - Child spans: which services were called?
   - Error spans: where did it fail?
   - Slow spans: where did latency accumulate?

4. Correlate with logs
   - Filter logs by trace ID to see all log entries for this request
   - Look for warnings or errors that precede the failure

5. Identify the root cause
   - Which span first shows an error?
   - Is the error in your code, a dependency, or infrastructure?
   - Was this a transient failure or a persistent bug?

Correlate test failures with production telemetry

When a test fails, query your observability platform:

  1. Search production errors for matching messages (last 7 days)
  2. Search traces for the same HTTP route with ERROR status
  3. Matches exist: the bug is real and affecting users -- prioritize the fix
  4. No matches: may be a test-only issue or a new bug not yet in production

This turns "probably flaky" into "confirmed production impact" or "test-only issue," enabling better prioritization.


Anti-Patterns

Ignoring production signals

The error tracker has 500 unresolved errors. Nobody looks at it. New errors added daily. The test suite passes, so the team assumes quality is fine.

Fix: Schedule a weekly 30-minute error review. Pull the top 10 new errors by frequency; for each, assign an owner, create a test, or mark as known/acceptable.

Testing only what is easy to observe

Teams test HTTP status codes and response times while ignoring data consistency, background job completion, and cache coherence.

Fix: Use distributed tracing to make invisible code paths visible. Add spans to background jobs, cache operations, and async workflows. If it runs in production, it should produce telemetry.

No feedback loop between production and testing

Production errors are handled by SRE. Tests are written by QA. Neither team shares information systematically. The same class of bugs recurs.

Fix: Establish the production-error-to-test pipeline above. Add to incident postmortems: "What test would have prevented this?" Create the test before closing the incident.

Over-instrumenting tests without acting on data

Thousands of metrics and logs emitted. Nobody analyzes them. Data collection has cost but no benefit.

Fix: Start with three specific questions you want to answer from test telemetry. Build those dashboards. Add more instrumentation only when you have a new question.

Using traces only for debugging, not for assertions

Traces treated as a post-break debugging tool rather than a source of test assertions to prevent breaks.

Fix: Add trace-based assertions to integration tests -- correct services called, efficient queries, expected cache hits. These catch regressions that HTTP-level assertions miss.


Done When

  • OpenTelemetry covers all critical code paths -- no high-traffic endpoints or key service boundaries are invisible in traces
  • Trace-based assertions exist for at least one key user journey, verifying service calls and span attributes, not just HTTP status
  • Log-informed test cases exist for known failure modes from production error analysis
  • Telemetry data (hot-path or error-rate matrix) has identified and prioritized at least one set of untested code paths
  • Observability signals are reviewed as part of post-deploy validation before a release is considered stable

Related Skills

SkillRelationship
testing-in-productionProduction observability is the prerequisite for safe production testing
synthetic-monitoringSynthetic probes produce telemetry that feeds into observability analysis
qa-metricsTelemetry-derived metrics (error rates, latency) feed into quality dashboards
ai-bug-triageAI can analyze production error patterns to suggest test priorities
api-testingTrace-based assertions strengthen API test evidence
ci-cd-integrationTest telemetry integrates with CI pipelines for trend analysis

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

37.44%
按下载量换算37

Claude

28.36%
按下载量换算28

Cursor

16.41%
按下载量换算16

Gemini CLI

8.57%
按下载量换算8

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

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

来源信息

继续浏览同类 Skills