{
  "schemaVersion": "1.0",
  "item": {
    "slug": "test-runner",
    "name": "Test Runner",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/cmanfre7/test-runner",
    "canonicalUrl": "https://clawhub.ai/cmanfre7/test-runner",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/test-runner",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=test-runner",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "slug": "test-runner",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-09T22:27:23.318Z",
      "expiresAt": "2026-05-16T22:27:23.318Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=test-runner",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=test-runner",
        "contentDisposition": "attachment; filename=\"test-runner-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "test-runner"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/test-runner"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/test-runner",
    "agentPageUrl": "https://openagent3.xyz/skills/test-runner/agent",
    "manifestUrl": "https://openagent3.xyz/skills/test-runner/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/test-runner/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "test-runner",
        "body": "Write and run tests across languages and frameworks."
      },
      {
        "title": "Framework Selection",
        "body": "LanguageUnit TestsIntegrationE2ETypeScript/JSVitest (preferred), JestSupertestPlaywrightPythonpytestpytest + httpxPlaywrightSwiftXCTestXCTestXCUITest"
      },
      {
        "title": "Vitest (TypeScript / JavaScript)",
        "body": "npm install -D vitest @testing-library/react @testing-library/jest-dom\n\n// vitest.config.ts\nimport { defineConfig } from 'vitest/config'\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'jsdom',\n    setupFiles: './tests/setup.ts',\n  },\n})\n\nnpx vitest              # Watch mode\nnpx vitest run          # Single run\nnpx vitest --coverage   # With coverage"
      },
      {
        "title": "Jest",
        "body": "npm install -D jest @types/jest ts-jest\n\nnpx jest                # Run all\nnpx jest --watch        # Watch mode\nnpx jest --coverage     # With coverage\nnpx jest path/to/test   # Single file"
      },
      {
        "title": "pytest (Python)",
        "body": "uv pip install pytest pytest-cov pytest-asyncio httpx\n\npytest                          # Run all\npytest -v                       # Verbose\npytest -x                       # Stop on first failure\npytest --cov=app                # With coverage\npytest tests/test_api.py -k \"test_login\"  # Specific test\npytest --tb=short               # Short tracebacks"
      },
      {
        "title": "XCTest (Swift)",
        "body": "swift test                      # Run all tests\nswift test --filter MyTests     # Specific test suite\nswift test --parallel           # Parallel execution"
      },
      {
        "title": "Playwright (E2E)",
        "body": "npm install -D @playwright/test\nnpx playwright install\n\nnpx playwright test                    # Run all\nnpx playwright test --headed           # With browser visible\nnpx playwright test --debug            # Debug mode\nnpx playwright test --project=chromium # Specific browser\nnpx playwright show-report             # View HTML report"
      },
      {
        "title": "TDD Workflow",
        "body": "Red — Write a failing test that describes the desired behavior.\nGreen — Write the minimum code to make the test pass.\nRefactor — Clean up the code while keeping tests green.\n\n┌─────────┐     ┌─────────┐     ┌──────────┐\n│  Write   │────▶│  Write  │────▶│ Refactor │──┐\n│  Test    │     │  Code   │     │  Code    │  │\n│  (Red)   │     │ (Green) │     │          │  │\n└─────────┘     └─────────┘     └──────────┘  │\n     ▲                                          │\n     └──────────────────────────────────────────┘"
      },
      {
        "title": "Arrange-Act-Assert",
        "body": "test('calculates total with tax', () => {\n  // Arrange\n  const cart = new Cart([{ price: 100, qty: 2 }]);\n\n  // Act\n  const total = cart.totalWithTax(0.08);\n\n  // Assert\n  expect(total).toBe(216);\n});"
      },
      {
        "title": "Testing Async Code",
        "body": "test('fetches user data', async () => {\n  const user = await getUser('123');\n  expect(user.name).toBe('Colt');\n});"
      },
      {
        "title": "Mocking",
        "body": "import { vi } from 'vitest';\n\nconst mockFetch = vi.fn().mockResolvedValue({\n  json: () => Promise.resolve({ id: 1, name: 'Test' }),\n});\nvi.stubGlobal('fetch', mockFetch);"
      },
      {
        "title": "Testing API Endpoints (Python)",
        "body": "import pytest\nfrom httpx import AsyncClient\nfrom app.main import app\n\n@pytest.mark.asyncio\nasync def test_get_users():\n    async with AsyncClient(app=app, base_url=\"http://test\") as client:\n        response = await client.get(\"/users\")\n    assert response.status_code == 200\n    assert isinstance(response.json(), list)"
      },
      {
        "title": "Testing React Components",
        "body": "import { render, screen, fireEvent } from '@testing-library/react';\nimport { Button } from './Button';\n\ntest('calls onClick when clicked', () => {\n  const handleClick = vi.fn();\n  render(<Button onClick={handleClick}>Click me</Button>);\n  fireEvent.click(screen.getByText('Click me'));\n  expect(handleClick).toHaveBeenCalledOnce();\n});"
      },
      {
        "title": "Coverage Commands",
        "body": "# JavaScript/TypeScript\nnpx vitest --coverage          # Vitest (uses v8 or istanbul)\nnpx jest --coverage            # Jest\n\n# Python\npytest --cov=app --cov-report=html    # HTML report\npytest --cov=app --cov-report=term    # Terminal output\npytest --cov=app --cov-fail-under=80  # Fail if < 80%\n\n# View HTML coverage report\nopen coverage/index.html       # macOS\nopen htmlcov/index.html        # Python"
      },
      {
        "title": "What to Test",
        "body": "Always test:\n\nPublic API / exported functions\nEdge cases: empty input, null, boundary values\nError handling: invalid input, network failures\nBusiness logic: calculations, state transitions\n\nDon't bother testing:\n\nPrivate implementation details\nFramework internals (React rendering, Express routing)\nTrivial getters/setters\nThird-party library behavior"
      }
    ],
    "body": "test-runner\n\nWrite and run tests across languages and frameworks.\n\nFramework Selection\nLanguage\tUnit Tests\tIntegration\tE2E\nTypeScript/JS\tVitest (preferred), Jest\tSupertest\tPlaywright\nPython\tpytest\tpytest + httpx\tPlaywright\nSwift\tXCTest\tXCTest\tXCUITest\nQuick Start by Framework\nVitest (TypeScript / JavaScript)\nnpm install -D vitest @testing-library/react @testing-library/jest-dom\n\n// vitest.config.ts\nimport { defineConfig } from 'vitest/config'\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'jsdom',\n    setupFiles: './tests/setup.ts',\n  },\n})\n\nnpx vitest              # Watch mode\nnpx vitest run          # Single run\nnpx vitest --coverage   # With coverage\n\nJest\nnpm install -D jest @types/jest ts-jest\n\nnpx jest                # Run all\nnpx jest --watch        # Watch mode\nnpx jest --coverage     # With coverage\nnpx jest path/to/test   # Single file\n\npytest (Python)\nuv pip install pytest pytest-cov pytest-asyncio httpx\n\npytest                          # Run all\npytest -v                       # Verbose\npytest -x                       # Stop on first failure\npytest --cov=app                # With coverage\npytest tests/test_api.py -k \"test_login\"  # Specific test\npytest --tb=short               # Short tracebacks\n\nXCTest (Swift)\nswift test                      # Run all tests\nswift test --filter MyTests     # Specific test suite\nswift test --parallel           # Parallel execution\n\nPlaywright (E2E)\nnpm install -D @playwright/test\nnpx playwright install\n\nnpx playwright test                    # Run all\nnpx playwright test --headed           # With browser visible\nnpx playwright test --debug            # Debug mode\nnpx playwright test --project=chromium # Specific browser\nnpx playwright show-report             # View HTML report\n\nTDD Workflow\nRed — Write a failing test that describes the desired behavior.\nGreen — Write the minimum code to make the test pass.\nRefactor — Clean up the code while keeping tests green.\n┌─────────┐     ┌─────────┐     ┌──────────┐\n│  Write   │────▶│  Write  │────▶│ Refactor │──┐\n│  Test    │     │  Code   │     │  Code    │  │\n│  (Red)   │     │ (Green) │     │          │  │\n└─────────┘     └─────────┘     └──────────┘  │\n     ▲                                          │\n     └──────────────────────────────────────────┘\n\nTest Patterns\nArrange-Act-Assert\ntest('calculates total with tax', () => {\n  // Arrange\n  const cart = new Cart([{ price: 100, qty: 2 }]);\n\n  // Act\n  const total = cart.totalWithTax(0.08);\n\n  // Assert\n  expect(total).toBe(216);\n});\n\nTesting Async Code\ntest('fetches user data', async () => {\n  const user = await getUser('123');\n  expect(user.name).toBe('Colt');\n});\n\nMocking\nimport { vi } from 'vitest';\n\nconst mockFetch = vi.fn().mockResolvedValue({\n  json: () => Promise.resolve({ id: 1, name: 'Test' }),\n});\nvi.stubGlobal('fetch', mockFetch);\n\nTesting API Endpoints (Python)\nimport pytest\nfrom httpx import AsyncClient\nfrom app.main import app\n\n@pytest.mark.asyncio\nasync def test_get_users():\n    async with AsyncClient(app=app, base_url=\"http://test\") as client:\n        response = await client.get(\"/users\")\n    assert response.status_code == 200\n    assert isinstance(response.json(), list)\n\nTesting React Components\nimport { render, screen, fireEvent } from '@testing-library/react';\nimport { Button } from './Button';\n\ntest('calls onClick when clicked', () => {\n  const handleClick = vi.fn();\n  render(<Button onClick={handleClick}>Click me</Button>);\n  fireEvent.click(screen.getByText('Click me'));\n  expect(handleClick).toHaveBeenCalledOnce();\n});\n\nCoverage Commands\n# JavaScript/TypeScript\nnpx vitest --coverage          # Vitest (uses v8 or istanbul)\nnpx jest --coverage            # Jest\n\n# Python\npytest --cov=app --cov-report=html    # HTML report\npytest --cov=app --cov-report=term    # Terminal output\npytest --cov=app --cov-fail-under=80  # Fail if < 80%\n\n# View HTML coverage report\nopen coverage/index.html       # macOS\nopen htmlcov/index.html        # Python\n\nWhat to Test\n\nAlways test:\n\nPublic API / exported functions\nEdge cases: empty input, null, boundary values\nError handling: invalid input, network failures\nBusiness logic: calculations, state transitions\n\nDon't bother testing:\n\nPrivate implementation details\nFramework internals (React rendering, Express routing)\nTrivial getters/setters\nThird-party library behavior"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/cmanfre7/test-runner",
    "publisherUrl": "https://clawhub.ai/cmanfre7/test-runner",
    "owner": "cmanfre7",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/test-runner",
    "downloadUrl": "https://openagent3.xyz/downloads/test-runner",
    "agentUrl": "https://openagent3.xyz/skills/test-runner/agent",
    "manifestUrl": "https://openagent3.xyz/skills/test-runner/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/test-runner/agent.md"
  }
}