testing-blocks

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Testing Blocks

测试Blocks

This skill guides you through testing code changes in AEM Edge Delivery Services projects. Testing follows a value-versus-cost philosophy: create and maintain tests when the value they bring exceeds the cost of creation and maintenance.
CRITICAL: Browser validation is MANDATORY. You cannot complete this skill without providing proof of functional testing in a real browser environment.
本技能将引导你完成AEM Edge Delivery Services项目中的代码变更测试。测试遵循价值-成本权衡原则:当测试带来的价值超过创建和维护的成本时,才创建并维护测试。
重要提示:浏览器验证是强制性要求。若未提供真实浏览器环境下的功能测试证明,将无法完成本技能。

Related Skills

相关技能

  • content-driven-development: Test content created during CDD serves as the basis for testing
  • building-blocks: Invokes this skill during Step 5 for comprehensive testing
  • block-collection-and-party: May provide reference test patterns from similar blocks
  • content-driven-development: CDD过程中创建的测试内容可作为测试基础
  • building-blocks: 在步骤5中调用本技能进行全面测试
  • block-collection-and-party: 可能提供类似Blocks的参考测试模式

When to Use This Skill

使用时机

Use this skill:
  • ✅ After implementing or modifying blocks
  • ✅ After changes to core scripts (scripts.js, delayed.js, aem.js)
  • ✅ After style changes (styles.css, lazy-styles.css)
  • ✅ After configuration changes that affect functionality
  • ✅ Before opening any pull request with code changes
This skill is typically invoked by the building-blocks skill during Step 5 (Test Implementation).
在以下场景使用本技能:
  • ✅ 实现或修改Blocks后
  • ✅ 修改核心脚本(scripts.js、delayed.js、aem.js)后
  • ✅ 修改样式(styles.css、lazy-styles.css)后
  • ✅ 修改影响功能的配置后
  • ✅ 发起任何包含代码变更的拉取请求前
本技能通常由building-blocks技能在步骤5(测试实现)中调用。

Testing Workflow

测试工作流

Track your progress:
  • Step 1: Run linting and fix issues
  • Step 2: Perform browser validation (MANDATORY)
  • Step 3: Determine if unit tests are needed (optional)
  • Step 4: Run existing tests and verify they pass
跟踪你的进度:
  • 步骤1:运行代码检查并修复问题
  • 步骤2:执行浏览器验证(强制性要求)
  • 步骤3:判断是否需要单元测试(可选)
  • 步骤4:运行现有测试并验证通过

Step 1: Run Linting

步骤1:运行代码检查

Run linting first to catch code quality issues:
bash
npm run lint
If linting fails:
bash
npm run lint:fix
Manually fix remaining issues that auto-fix couldn't handle.
Success criteria:
  • ✅ Linting passes with no errors
  • ✅ Code follows project standards
Mark complete when:
npm run lint
passes with no errors

先运行代码检查以捕获代码质量问题:
bash
npm run lint
若代码检查失败:
bash
npm run lint:fix
手动修复自动修复无法处理的剩余问题
成功标准:
  • ✅ 代码检查无错误通过
  • ✅ 代码符合项目规范
标记完成时机:
npm run lint
无错误通过

Step 2: Browser Validation (MANDATORY)

步骤2:浏览器验证(强制性要求)

CRITICAL: You must test in a real browser and provide proof.
重要提示:你必须在真实浏览器中测试并提供证明。

What to Test

测试内容

Load test content URL(s) in browser and validate:
  • ✅ Block/functionality renders correctly
  • ✅ Responsive behavior (mobile, tablet, desktop viewports)
  • ✅ No console errors
  • ✅ Visual appearance matches requirements/acceptance criteria
  • ✅ Interactive behavior works (if applicable)
  • ✅ All variants render correctly (if applicable)
在浏览器中加载测试内容URL并验证:
  • ✅ Block/功能渲染正确
  • ✅ 响应式表现(移动端、平板端、桌面端视口)
  • ✅ 控制台无错误
  • ✅ 视觉表现符合需求/验收标准
  • ✅ 交互功能正常(若适用)
  • ✅ 所有变体渲染正确(若适用)

How to Test

测试方法

Choose the method that makes most sense given your available tools:
Option 1: Browser/Playwright MCP (Recommended)
If you have MCP browser or Playwright tools available, use them directly:
  • Navigate to test content URL
  • Take accessibility snapshots to inspect rendered content (preferred for interaction)
  • Take screenshots at different viewports for visual validation
    • Consider both full-page screenshots and element-specific screenshots of the block being tested
  • Interact with elements as needed
  • Most efficient for agents with tool access
Option 2: Playwright automation
Write one (or more) temporary test scripts to validate functionality with playwright and capture snapshots/screenshots for inspection and validation.
javascript
// test-my-block.js (temporary - don't commit)
import { chromium } from 'playwright';

async function test() {
  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();

  // Navigate and wait for block
  await page.goto('http://localhost:3000/path/to/test');
  await page.waitForSelector('.my-block');

  // Inspect accessibility tree (useful for validating structure)
  const accessibilityTree = await page.accessibility.snapshot();
  console.log('Accessibility tree:', JSON.stringify(accessibilityTree, null, 2));
  
  // Optionally save to file for easier analysis
  await require('fs').promises.writeFile(
    'accessibility-tree.json',
    JSON.stringify(accessibilityTree, null, 2)
  );

  // Test viewports and take screenshots
  await page.setViewportSize({ width: 375, height: 667 });
  await page.screenshot({ path: 'mobile.png', fullPage: true });
  await page.locator('.my-block').screenshot({ path: 'mobile-block.png' });

  await page.setViewportSize({ width: 768, height: 1024 });
  await page.screenshot({ path: 'tablet.png', fullPage: true });
  await page.locator('.my-block').screenshot({ path: 'tablet-block.png' });

  await page.setViewportSize({ width: 1200, height: 800 });
  await page.screenshot({ path: 'desktop.png', fullPage: true });
  await page.locator('.my-block').screenshot({ path: 'desktop-block.png' });

  // Check for console errors
  page.on('console', msg => console.log('Browser:', msg.text()));

  await browser.close();
}

test().catch(console.error);
Run:
node test-my-block.js
then delete the script and analyze the resulting artifacts.
Option 3: Manual browser testing
Use a standard web browser with dev tools:
  1. Navigate to test content:
    http://localhost:3000/path/to/test/content
  2. Use browser dev tools responsive mode to test viewports:
    • Mobile: <600px (e.g., 375px)
    • Tablet: 600-900px (e.g., 768px)
    • Desktop: >900px (e.g., 1200px)
  3. Check console for errors at each viewport
  4. Take screenshots as proof (browser screenshot tool or dev tools)
根据可用工具选择最适合的方法:
选项1:浏览器/Playwright MCP(推荐)
若你拥有MCP浏览器或Playwright工具,直接使用:
  • 导航至测试内容URL
  • 拍摄可访问性快照以检查渲染内容(交互测试首选)
  • 在不同视口下截图进行视觉验证
    • 考虑同时截取完整页面截图和被测Block的元素特定截图
  • 根据需要与元素交互
  • 对拥有工具权限的Agent来说效率最高
选项2:Playwright自动化
编写一个(或多个)临时测试脚本,使用Playwright验证功能并捕获快照/截图以供检查和验证。
javascript
// test-my-block.js (临时文件 - 不要提交)
import { chromium } from 'playwright';

async function test() {
  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();

  // 导航并等待Block加载
  await page.goto('http://localhost:3000/path/to/test');
  await page.waitForSelector('.my-block');

  // 检查可访问性树(用于验证结构)
  const accessibilityTree = await page.accessibility.snapshot();
  console.log('Accessibility tree:', JSON.stringify(accessibilityTree, null, 2));
  
  // 可选:保存到文件以便分析
  await require('fs').promises.writeFile(
    'accessibility-tree.json',
    JSON.stringify(accessibilityTree, null, 2)
  );

  // 测试不同视口并截图
  await page.setViewportSize({ width: 375, height: 667 });
  await page.screenshot({ path: 'mobile.png', fullPage: true });
  await page.locator('.my-block').screenshot({ path: 'mobile-block.png' });

  await page.setViewportSize({ width: 768, height: 1024 });
  await page.screenshot({ path: 'tablet.png', fullPage: true });
  await page.locator('.my-block').screenshot({ path: 'tablet-block.png' });

  await page.setViewportSize({ width: 1200, height: 800 });
  await page.screenshot({ path: 'desktop.png', fullPage: true });
  await page.locator('.my-block').screenshot({ path: 'desktop-block.png' });

  // 检查控制台错误
  page.on('console', msg => console.log('Browser:', msg.text()));

  await browser.close();
}

test().catch(console.error);
运行:
node test-my-block.js
,然后删除脚本并分析生成的产物。
选项3:手动浏览器测试
使用标准浏览器搭配开发者工具:
  1. 导航至测试内容:
    http://localhost:3000/path/to/test/content
  2. 使用浏览器开发者工具的响应式模式测试不同视口:
    • 移动端:<600px(例如375px)
    • 平板端:600-900px(例如768px)
    • 桌面端:>900px(例如1200px)
  3. 在每个视口下检查控制台是否有错误
  4. 截图作为证明(使用浏览器截图工具或开发者工具)

Validation Against Acceptance Criteria

对照验收标准验证

If acceptance criteria provided (from CDD Step 2):
  • Review each criterion
  • Test specific scenarios mentioned
  • Verify all criteria are met
If design/mockup screenshots provided:
  • Compare implementation to design
  • Verify visual alignment
  • Note any intentional deviations
若提供了验收标准(来自CDD步骤2):
  • 逐一检查每个标准
  • 测试提到的特定场景
  • 验证所有标准均已满足
若提供了设计/ mockup截图:
  • 将实现效果与设计对比
  • 验证视觉对齐
  • 记录任何有意的偏差

Proof of Testing

测试证明

You must provide:
  • ✅ Screenshots of test content in browser (at least one viewport)
  • ✅ Confirmation no console errors
  • ✅ Confirmation acceptance criteria met (if provided)
Success criteria:
  • ✅ All test content loads and renders correctly
  • ✅ Responsive behavior validated across viewports
  • ✅ No console errors
  • ✅ Screenshots captured as proof
  • ✅ Acceptance criteria validated (if provided)
Mark complete when: Browser testing complete with screenshots as proof

你必须提供:
  • ✅ 浏览器中测试内容的截图(至少一个视口)
  • ✅ 控制台无错误的确认
  • ✅ 验收标准已满足的确认(若提供)
成功标准:
  • ✅ 所有测试内容加载并渲染正确
  • ✅ 已跨视口验证响应式表现
  • ✅ 控制台无错误
  • ✅ 已捕获截图作为证明
  • ✅ 已验证验收标准(若提供)
标记完成时机: 浏览器测试完成并提供截图证明

Step 3: Unit Tests (Optional)

步骤3:单元测试(可选)

Determine if unit tests are needed for this change.
Write unit tests when:
  • ✅ Logic-heavy functions (calculations, transformations)
  • ✅ Utility functions used across multiple blocks
  • ✅ Data processing or API integrations
  • ✅ Complex business logic
Skip unit tests when:
  • ❌ Simple DOM manipulation
  • ❌ CSS-only changes
  • ❌ Straightforward decoration logic
  • ❌ Changes easily validated in browser
For guidance on what to test: See
resources/testing-philosophy.md
If unit tests needed:
bash
undefined
判断本次变更是否需要单元测试。
在以下场景编写单元测试:
  • ✅ 逻辑密集型函数(计算、转换)
  • ✅ 多个Blocks共用的工具函数
  • ✅ 数据处理或API集成
  • ✅ 复杂业务逻辑
在以下场景跳过单元测试:
  • ❌ 简单DOM操作
  • ❌ 仅CSS变更
  • ❌ 直接的装饰逻辑
  • ❌ 可在浏览器中轻松验证的变更
测试内容指导: 参见
resources/testing-philosophy.md
若需要单元测试:
bash
undefined

Verify test setup (see resources/vitest-setup.md if not configured)

验证测试环境配置(若未配置,参见resources/vitest-setup.md)

npm test
npm test

Write test for utility function

为工具函数编写测试

test/utils/my-utility.test.js

test/utils/my-utility.test.js

import { describe, it, expect } from 'vitest'; import { myUtility } from '../../scripts/utils/my-utility.js';
describe('myUtility', () => { it('should transform input correctly', () => { expect(myUtility('input')).toBe('OUTPUT'); }); });

**For detailed unit testing guidance:** See `resources/unit-testing.md`

**Success criteria:**
- ✅ Unit tests written for logic-heavy code
- ✅ Tests pass: `npm test`
- ✅ OR determined unit tests not needed

**Mark complete when:** Unit tests written and passing, or determined not needed

---
import { describe, it, expect } from 'vitest'; import { myUtility } from '../../scripts/utils/my-utility.js';
describe('myUtility', () => { it('should transform input correctly', () => { expect(myUtility('input')).toBe('OUTPUT'); }); });

**详细单元测试指导:** 参见`resources/unit-testing.md`

**成功标准:**
- ✅ 为逻辑密集型代码编写了单元测试
- ✅ 测试通过:`npm test`
- ✅ 或已确定不需要单元测试

**标记完成时机:** 单元测试编写并通过,或已确定不需要

---

Step 4: Run Existing Tests

步骤4:运行现有测试

Verify your changes don't break existing functionality:
bash
npm test
If tests fail:
  1. Read error message carefully
  2. Run single test to isolate:
    npm test -- path/to/test.js
  3. Fix code or update test if expectations changed
  4. Re-run full test suite
Success criteria:
  • ✅ All existing tests pass
  • ✅ No regressions introduced
Mark complete when:
npm test
passes with no failures
验证你的变更未破坏现有功能:
bash
npm test
若测试失败:
  1. 仔细阅读错误信息
  2. 运行单个测试以隔离问题:
    npm test -- path/to/test.js
  3. 修复代码或更新测试(若预期结果已变更)
  4. 重新运行完整测试套件
成功标准:
  • ✅ 所有现有测试通过
  • ✅ 未引入回归问题
标记完成时机:
npm test
无失败通过

Troubleshooting

故障排除

For detailed troubleshooting guide, see
resources/troubleshooting.md
.
Common issues:
详细故障排除指南参见
resources/troubleshooting.md
常见问题:

Tests fail

测试失败

  • Read error message carefully
  • Run single test:
    npm test -- path/to/test.js
  • Fix code or update test
  • 仔细阅读错误信息
  • 运行单个测试:
    npm test -- path/to/test.js
  • 修复代码或更新测试

Linting fails

代码检查失败

  • Run
    npm run lint:fix
  • Manually fix remaining issues
  • 运行
    npm run lint:fix
  • 手动修复剩余问题

Browser tests fail

浏览器测试失败

  • Verify dev server running:
    aem up --html-folder drafts
  • Check test content exists in
    drafts/tmp/
  • Verify URL uses
    /tmp/
    path:
    http://localhost:3000/drafts/tmp/my-block
  • Add waits:
    await page.waitForSelector('.block')
  • 验证开发服务器是否运行:
    aem up --html-folder drafts
  • 检查测试内容是否存在于
    drafts/tmp/
  • 验证URL是否使用
    /tmp/
    路径:
    http://localhost:3000/drafts/tmp/my-block
  • 添加等待:
    await page.waitForSelector('.block')

Resources

资源

  • Unit Testing:
    resources/unit-testing.md
    - Complete guide to writing and maintaining unit tests
  • Troubleshooting:
    resources/troubleshooting.md
    - Solutions to common testing issues
  • Vitest Setup:
    resources/vitest-setup.md
    - One-time configuration guide
  • Testing Philosophy:
    resources/testing-philosophy.md
    - Guide on what and how to test
  • 单元测试:
    resources/unit-testing.md
    - 编写和维护单元测试的完整指南
  • 故障排除:
    resources/troubleshooting.md
    - 常见测试问题的解决方案
  • Vitest配置:
    resources/vitest-setup.md
    - 一次性配置指南
  • 测试理念:
    resources/testing-philosophy.md
    - 测试内容与方法的指导

Integration with Building Blocks Skill

与Building Blocks技能的集成

The building-blocks skill invokes this skill during Step 5 (Test Implementation).
Inputs received from building-blocks:
  • Block name being tested
  • Test content URL(s) (from CDD Step 4)
  • Any variants that need testing
  • Screenshots of existing implementation/design/mockup to verify against (if provided)
  • Acceptance criteria to verify (from CDD Step 2)
Expected outputs to return to building-blocks:
  • ✅ Confirmation all testing steps complete
  • ✅ Screenshots from browser testing as proof
  • ✅ Confirmation linting passes
  • ✅ Confirmation tests pass
  • ✅ Any issues discovered and resolved
building-blocks技能会在步骤5(测试实现)中调用本技能。
从building-blocks接收的输入:
  • 被测Block的名称
  • 测试内容URL(来自CDD步骤4)
  • 需要测试的所有变体
  • 用于对比的现有实现/设计/mockup截图(若提供)
  • 需要验证的验收标准(来自CDD步骤2)
需要返回给building-blocks的输出:
  • ✅ 所有测试步骤完成的确认
  • ✅ 浏览器测试的截图证明
  • ✅ 代码检查通过的确认
  • ✅ 测试通过的确认
  • ✅ 发现并解决的所有问题