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

testing-patterns测试模式

Agent Skill

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

总安装

692

周安装

28

下载量

217
Local Agent

安装说明

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

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

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

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

命令行安装

复制命令到本机终端执行。当前暂无明确安装命令,请以来源页面说明为准。

简介

testing-patterns 用于辅助测试设计、自动化测试和回归验证,适合在 Local Agent 中学习标准测试模式时使用。

  • 提供经过验证的测试组织方法与最佳实践。
  • 适用于中大型项目的测试架构设计参考。
  • 使用前需确认与当前技术栈的匹配度。testing-patterns 属于研究检索类 Skill,可作为该场景下的辅助能力补充。
  • 建议查阅原始文档了解具体支持的模式类型。

SKILL.md

Testing Patterns & Best Practices

Testing Principles

1. Test Behavior, Not Implementation

  • Test what the code does, not how it does it
  • Tests shouldn't break when refactoring
  • Focus on inputs and outputs

2. Arrange-Act-Assert (AAA)

// Arrange - Set up test data
const user = { name: 'John', email: 'john@example.com' }

// Act - Execute the code
const result = validateUser(user)

// Assert - Verify the outcome
expect(result.isValid).toBe(true)

3. Test Isolation

  • Each test should be independent
  • No shared state between tests
  • Clean up after each test

Unit Testing Patterns

Basic Test Structure

describe('UserService', () => {
  describe('createUser', () => {
    it('should create user with valid data', async () => {
      const userData = { name: 'John', email: 'john@example.com' }
      const result = await userService.createUser(userData)

      expect(result).toMatchObject({
        id: expect.any(String),
        name: 'John',
        email: 'john@example.com'
      })
    })

    it('should throw error for invalid email', async () => {
      const userData = { name: 'John', email: 'invalid' }

      await expect(userService.createUser(userData))
        .rejects
        .toThrow('Invalid email format')
    })
  })
})

Mocking Patterns

// Mock a module
jest.mock('./database', () => ({
  query: jest.fn()
}))

// Mock implementation
const mockQuery = jest.mocked(query)
mockQuery.mockResolvedValue([{ id: '1', name: 'Test' }])

// Spy on method
const spy = jest.spyOn(userService, 'sendEmail')
spy.mockResolvedValue(undefined)

// Verify mock was called
expect(mockQuery).toHaveBeenCalledWith(
  'SELECT * FROM users WHERE id = ?',
  ['123']
)
expect(mockQuery).toHaveBeenCalledTimes(1)

Testing Async Code

// Async/await
it('should fetch user data', async () => {
  const user = await fetchUser('123')
  expect(user.name).toBe('John')
})

// Testing promises that reject
it('should handle fetch errors', async () => {
  await expect(fetchUser('invalid'))
    .rejects
    .toThrow('User not found')
})

// Testing timers
it('should debounce calls', () => {
  jest.useFakeTimers()

  const callback = jest.fn()
  const debounced = debounce(callback, 100)

  debounced()
  debounced()
  debounced()

  expect(callback).not.toHaveBeenCalled()

  jest.advanceTimersByTime(100)

  expect(callback).toHaveBeenCalledTimes(1)
})

Testing Error Handling

it('should handle network errors gracefully', async () => {
  mockFetch.mockRejectedValue(new Error('Network error'))

  const result = await fetchDataWithRetry('/api/data')

  expect(result).toEqual({ error: 'Failed to fetch data' })
  expect(mockFetch).toHaveBeenCalledTimes(3) // Retried 3 times
})

React Testing Library Patterns

Component Testing

import { render, screen, fireEvent, waitFor } from '@testing-library/react'

describe('LoginForm', () => {
  it('should submit form with credentials', async () => {
    const onSubmit = jest.fn()
    render(<LoginForm onSubmit={onSubmit} />)

    // Find elements by accessible roles/text
    const emailInput = screen.getByLabelText(/email/i)
    const passwordInput = screen.getByLabelText(/password/i)
    const submitButton = screen.getByRole('button', { name: /sign in/i })

    // Interact with form
    fireEvent.change(emailInput, { target: { value: 'test@example.com' } })
    fireEvent.change(passwordInput, { target: { value: 'password123' } })
    fireEvent.click(submitButton)

    // Assert
    await waitFor(() => {
      expect(onSubmit).toHaveBeenCalledWith({
        email: 'test@example.com',
        password: 'password123'
      })
    })
  })

  it('should display validation errors', async () => {
    render(<LoginForm onSubmit={jest.fn()} />)

    fireEvent.click(screen.getByRole('button', { name: /sign in/i }))

    expect(await screen.findByText(/email is required/i)).toBeInTheDocument()
    expect(await screen.findByText(/password is required/i)).toBeInTheDocument()
  })
})

Testing Custom Hooks

import { renderHook, act } from '@testing-library/react'

describe('useCounter', () => {
  it('should increment counter', () => {
    const { result } = renderHook(() => useCounter(0))

    expect(result.current.count).toBe(0)

    act(() => {
      result.current.increment()
    })

    expect(result.current.count).toBe(1)
  })

  it('should reset counter', () => {
    const { result } = renderHook(() => useCounter(5))

    act(() => {
      result.current.increment()
      result.current.reset()
    })

    expect(result.current.count).toBe(5)
  })
})

Testing with Context

const wrapper = ({ children }) => (
  <AuthProvider>
    <ThemeProvider>
      {children}
    </ThemeProvider>
  </AuthProvider>
)

it('should use auth context', () => {
  render(<UserProfile />, { wrapper })

  expect(screen.getByText('Logged in as John')).toBeInTheDocument()
})

Playwright E2E Patterns

Basic Page Testing

import { test, expect } from '@playwright/test'

test.describe('Authentication', () => {
  test('should login successfully', async ({ page }) => {
    await page.goto('/login')

    await page.fill('[data-testid="email"]', 'user@example.com')
    await page.fill('[data-testid="password"]', 'password123')
    await page.click('[data-testid="submit"]')

    await expect(page).toHaveURL('/dashboard')
    await expect(page.locator('[data-testid="welcome"]'))
      .toContainText('Welcome, User')
  })

  test('should show error for invalid credentials', async ({ page }) => {
    await page.goto('/login')

    await page.fill('[data-testid="email"]', 'wrong@example.com')
    await page.fill('[data-testid="password"]', 'wrongpassword')
    await page.click('[data-testid="submit"]')

    await expect(page.locator('[data-testid="error"]'))
      .toContainText('Invalid credentials')
  })
})

Page Object Model

// pages/LoginPage.ts
export class LoginPage {
  constructor(private page: Page) {}

  async goto() {
    await this.page.goto('/login')
  }

  async login(email: string, password: string) {
    await this.page.fill('[data-testid="email"]', email)
    await this.page.fill('[data-testid="password"]', password)
    await this.page.click('[data-testid="submit"]')
  }

  async getErrorMessage() {
    return this.page.locator('[data-testid="error"]').textContent()
  }
}

// tests/login.spec.ts
test('should login', async ({ page }) => {
  const loginPage = new LoginPage(page)
  await loginPage.goto()
  await loginPage.login('user@example.com', 'password123')

  await expect(page).toHaveURL('/dashboard')
})

API Testing with Playwright

test('should create user via API', async ({ request }) => {
  const response = await request.post('/api/users', {
    data: {
      name: 'John',
      email: 'john@example.com'
    }
  })

  expect(response.ok()).toBeTruthy()

  const user = await response.json()
  expect(user).toMatchObject({
    id: expect.any(String),
    name: 'John',
    email: 'john@example.com'
  })
})

Visual Testing

test('should match screenshot', async ({ page }) => {
  await page.goto('/dashboard')

  await expect(page).toHaveScreenshot('dashboard.png', {
    maxDiffPixels: 100
  })
})

Test Data Patterns

Factory Pattern

// factories/user.factory.ts
export function createUser(overrides?: Partial<User>): User {
  return {
    id: faker.string.uuid(),
    name: faker.person.fullName(),
    email: faker.internet.email(),
    createdAt: new Date(),
    ...overrides
  }
}

// Usage in tests
const user = createUser({ name: 'Custom Name' })

Builder Pattern

class UserBuilder {
  private user: Partial<User> = {}

  withName(name: string) {
    this.user.name = name
    return this
  }

  withEmail(email: string) {
    this.user.email = email
    return this
  }

  asAdmin() {
    this.user.role = 'admin'
    return this
  }

  build(): User {
    return {
      id: faker.string.uuid(),
      name: this.user.name ?? faker.person.fullName(),
      email: this.user.email ?? faker.internet.email(),
      role: this.user.role ?? 'user',
      createdAt: new Date()
    }
  }
}

// Usage
const adminUser = new UserBuilder().withName('Admin').asAdmin().build()

Coverage Requirements

Minimum Coverage Targets

  • 80% overall for all code
  • 100% required for:

- Financial calculations - Authentication logic - Security-critical code - Core business logic

Running Coverage

# Jest
npm test -- --coverage

# Vitest
npx vitest run --coverage

# Check thresholds
npm test -- --coverage --coverageThreshold='{"global":{"lines":80}}'

Edge Cases to Test

  • Null/undefined inputs
  • Empty arrays/strings
  • Boundary values (0, -1, MAX_INT)
  • Unicode characters
  • Very long strings
  • Concurrent operations
  • Network failures
  • Timeout scenarios
  • Permission denied errors

Anti-Patterns to Avoid

Testing Implementation Details

// BAD: Testing internal state
expect(component.state.isLoading).toBe(true)

// GOOD: Testing visible behavior
expect(screen.getByTestId('spinner')).toBeInTheDocument()

Brittle Selectors

// BAD: Fragile selectors
page.locator('.btn-primary.mt-4.px-6')

// GOOD: Semantic selectors
page.locator('[data-testid="submit-button"]')
page.getByRole('button', { name: 'Submit' })

Over-Mocking

// BAD: Mocking everything
jest.mock('./utils')
jest.mock('./helpers')
jest.mock('./constants')

// GOOD: Only mock external dependencies
jest.mock('./api-client')

Checklist

  • Tests follow AAA pattern
  • Each test has single assertion focus
  • No shared state between tests
  • Proper cleanup in afterEach
  • Meaningful test descriptions
  • Edge cases covered
  • Async code properly awaited
  • Coverage meets thresholds

适合场景

01

用户想查找某类 Agent Skill 时

02

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

03

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

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

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

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

平台分布

Local Agent

91.2%
按下载量换算198

安全审计

暂无安全审计结果可展示。

权限和风险

操作浏览器

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

安装前确认

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

来源信息

继续浏览同类 Skills