← Back to list

dcyfr-testing
by dcyfr
DCYFR Labs
⭐ 2🍴 0📅 Jan 25, 2026
SKILL.md
name: dcyfr-testing description: Testing patterns, 99% pass rate target, strategic skips, and E2E workflows license: MIT compatibility: opencode metadata: audience: developers workflow: testing category: quality-assurance
What I do
I ensure DCYFR testing follows quality standards:
- 99% test pass rate target (not 100%)
- Strategic skips for valid reasons (not failures)
- When/when-not-to-test decision making
- E2E testing with Playwright
- Test data protection with environment checks
When to use me
✅ Use this skill when:
- Writing new tests for components or API routes
- Deciding whether to skip tests strategically
- Setting up E2E test suites
- Fixing failing tests
- Reviewing test coverage
❌ Don't use this skill for:
- Production deployments (tests run in CI)
- Manual testing workflows
- Performance benchmarking (use separate tools)
Core Rules
1. 99% Pass Rate Target (Not 100%)
Why not 100%?
- Strategic skips are acceptable for valid reasons
- Flaky tests should be skipped temporarily (with GitHub issues)
- Environment-specific tests (e.g., requires Redis) can be skipped
Current status: 1659/1717 tests passing (96.6%)
2. Strategic Skips vs Failures
// ✅ CORRECT: Strategic skip with reason
test.skip('renders with Redis data', () => {
// Skipped: Requires Redis connection (issue #123)
});
// ❌ WRONG: Failing test left as-is
test('renders with Redis data', () => {
expect(fetchData()).resolves.toBe(data); // Fails in CI
});
3. When to Write Tests
✅ Always test:
- Public API routes (validation, error handling)
- Utility functions (pure functions, data transformations)
- Critical user flows (auth, payments, form submissions)
- Bug fixes (regression tests)
⚠️ Sometimes test:
- UI components (if complex logic or many props)
- Integration points (database, external APIs)
- Edge cases (boundary conditions)
❌ Don't test:
- Simple pass-through components (
<div>{children}</div>) - Third-party library internals
- Implementation details (use public APIs)
Test Commands
# Run tests once (no watch) - RECOMMENDED for AI agents
npm run test:run
# Run specific test file
npm run test:run src/components/blog/post-card.test.tsx
# Run E2E tests
npm run test:e2e
# Run E2E in headed mode (see browser)
npm run test:e2e:headed
# Full quality check (type + lint + test)
npm run check
⚠️ For AI Agents: Always use npm run test:run instead of npm test to avoid watch mode hanging.
Common Test Patterns
Component Test
import { render, screen } from '@testing-library/react';
import { PostCard } from './post-card';
describe('PostCard', () => {
it('renders post title and excerpt', () => {
render(
<PostCard
title="Test Post"
excerpt="Test excerpt"
date="2024-01-01"
slug="test-post"
/>
);
expect(screen.getByText('Test Post')).toBeInTheDocument();
expect(screen.getByText('Test excerpt')).toBeInTheDocument();
});
});
API Route Test
import { POST } from './route';
import { NextRequest } from 'next/server';
describe('/api/submit', () => {
it('validates required fields', async () => {
const request = new NextRequest('http://localhost:3000/api/submit', {
method: 'POST',
body: JSON.stringify({}),
});
const response = await POST(request);
const data = await response.json();
expect(response.status).toBe(400);
expect(data.error).toBe('Missing required fields');
});
});
Utility Function Test
import { formatDate } from './date-utils';
describe('formatDate', () => {
it('formats date as YYYY-MM-DD', () => {
expect(formatDate(new Date('2024-01-15'))).toBe('2024-01-15');
});
it('handles invalid dates', () => {
expect(formatDate(null)).toBe('');
});
});
E2E Testing with Playwright
Basic E2E Test
import { test, expect } from '@playwright/test';
test('navigates to blog and filters by category', async ({ page }) => {
await page.goto('/blog');
await expect(page.getByRole('heading', { name: 'Blog' })).toBeVisible();
await page.getByRole('button', { name: 'Web Development' }).click();
await expect(page.getByText('Showing posts in: Web Development')).toBeVisible();
});
Authenticated E2E Test
test.use({ storageState: 'playwright/.auth/user.json' });
test('creates new post as admin', async ({ page }) => {
await page.goto('/admin/posts/new');
await page.fill('[name="title"]', 'New Post');
await page.fill('[name="content"]', 'Post content');
await page.click('[type="submit"]');
await expect(page.getByText('Post created')).toBeVisible();
});
Test Data Protection
All test data MUST have environment checks:
// ✅ CORRECT: Environment-protected test data
if (process.env.NODE_ENV !== 'production' && process.env.VERCEL_ENV !== 'production') {
await redis.set('test:user:123', { name: 'Test User' });
}
// ❌ WRONG: No environment checks
await redis.set('test:user:123', { name: 'Test User' });
Strategic Skip Reasons
Valid reasons to skip tests:
- Environment-specific - Requires Redis, Postgres, etc.
- Flaky test - Intermittent failures (create GitHub issue)
- Component refactor planned - Will be rewritten soon
- CI timing issues - E2E tests timeout in CI only
- External dependency - Requires third-party API
Related Documentation
- Full testing patterns:
.github/agents/patterns/TESTING_PATTERNS.md - Test data prevention:
.github/agents/enforcement/TEST_DATA_PREVENTION.md - Automated testing guide:
docs/testing/automated-testing-guide.md
Approval Gates
Testing compliance is FLEXIBLE (warning only):
- ⚠️ Target: ≥99% test pass rate
- ⚠️ Strategic skips allowed (document reason)
- ✅ Must maintain ≥95% pass rate minimum
- ✅ All tests must run (no permanent skips without issues)
Score
Total Score
65/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon


