Dev Test — Development & Testing SOP
Overview
A structured workflow for implementing code changes with quality built in. Covers the full cycle from understanding the codebase to having a verified, reviewable diff.
Use cases: Bug fixes, feature development, refactoring, open-source contributions, any code change that needs to be correct and maintainable.
Workflow
Phase 1: Study Before Coding
Never write code before understanding the context. This phase prevents wasted effort and bad designs.
1a. Understand the project conventions
Check for and read these files (if they exist):
- -
CONTRIBUTING.md — contribution guidelines - INLINECODE1 — formatting rules
- INLINECODE2 /
package.json / Makefile — project config, linting, formatting - INLINECODE5 /
.flake8 / .eslintrc — code style rules
1b. Study the area of change
- - Read the module(s) you'll be modifying
- Trace the execution path around the bug/feature
- Understand data flow: what goes in, what comes out
- Note dependencies: what other modules interact with this code
1c. Study existing tests
- - Find the test directory structure:
tests/, __tests__/, INLINECODE10 - Note the test framework: pytest, jest, go test, JUnit, etc.
- Study naming conventions:
test_feature.py, feature.test.ts, INLINECODE13 - Note fixture/setup patterns used
- Check for test utilities, factories, or mocks
1d. Draft a mental model
Before writing code, articulate:
- - What needs to change (specific behavior)
- Where in the code (files, functions, classes)
- How you'll change it (approach)
- What could go wrong (edge cases, regressions)
Phase 2: Implement
Core principles
- 1. Minimal, focused changes
- Fix the bug / add the feature. Nothing else.
- Avoid unrelated formatting changes, import reordering, or drive-by refactors.
- If you spot something else to fix, note it for a separate commit/PR.
- 2. Follow existing patterns
- Match the codebase's style, not your preferred style
- Use the same naming conventions, indentation, comment style
- If the project uses
snake_case, don't introduce INLINECODE15
- 3. Add comments for non-obvious logic
- "Why" comments, not "what" comments
- Explain trade-offs, workarounds, and intentional decisions
- 4. Design for quality
| Principle | Meaning | Example |
|-----------|---------|---------|
| Defense-in-depth | Layer multiple protections | Validate input at API + service + DB layer |
| Backward compatibility | Don't break existing behavior | Add new params with defaults |
| Graceful degradation | Handle missing features | Platform-specific code falls back safely |
| Extensibility | Prefer composable designs | Plugin/middleware over hardcoded switch |
| Single responsibility | One function = one job | Extract logic instead of growing functions |
Phase 3: Write Tests
Test categories (implement in order)
- 1. Fix verification — prove the bug is fixed / feature works
CODEBLOCK0
- 2. Edge cases — boundary conditions
CODEBLOCK1
- 3. Error handling — invalid inputs, failure paths
CODEBLOCK2
- 4. Regression — existing behavior preserved
CODEBLOCK3
Test writing guidelines
- - One assertion per test (ideally) — makes failures easy to diagnose
- Descriptive names —
test_oauth_token_refreshes_when_expired not INLINECODE17 - Arrange-Act-Assert pattern:
def test_feature():
# Arrange
input_data = create_test_data()
# Act
result = feature(input_data)
# Assert
assert result.status == "success"
- - Use fixtures for reusable setup
- Mock external dependencies — network calls, file system, databases
- Test behavior, not implementation — don't assert on internal state
Phase 4: Run Tests
Progressive testing strategy
CODEBLOCK5
Handling test results
| Scenario | Action |
|---|
| All pass ✅ | Proceed to diff review |
| Your tests fail |
Fix the code, re-run |
| Pre-existing failures | Note them, don't fix (out of scope) |
| Flaky tests (pass/fail randomly) | Run 3x to confirm flakiness, note in PR |
| Tests you can't run (need env/infra) | Note in PR, explain what you tested manually |
Phase 5: Review the Diff
Before committing, review every line of your diff.
CODEBLOCK6
Diff review checklist
- - [ ] Every change is intentional (no accidental edits)
- [ ] No debug prints, TODO comments, or temporary code left in
- [ ] No secrets, tokens, or personal paths hardcoded
- [ ] No unrelated formatting changes
- [ ] All new functions/classes have appropriate docstrings/comments
- [ ] Test coverage looks adequate for the changes
- [ ] File additions are in the right directories
Phase 6: Commit
CODEBLOCK7
Commit message format
CODEBLOCK8
| Type | When |
|---|
| INLINECODE18 | Bug fix |
| INLINECODE19 |
New feature |
|
refactor | Code restructure (no behavior change) |
|
test | Adding/fixing tests only |
|
docs | Documentation changes only |
|
chore | Build/tooling/dependency changes |
Output
- - Committed code changes + tests on feature branch
- All tests passing
- Clean, reviewable diff
Tips
- - This skill works standalone for any development task.
- In a contribution pipeline, it follows repo-setup and feeds into pr-pilot.
- For large features, repeat Phase 2-5 in small increments rather than one big change.
- When pair-programming with AI: have the AI study the codebase (Phase 1) before asking it to implement anything.
开发测试 — 开发与测试标准操作流程
概述
一套结构化工作流程,用于在代码变更中内建质量保障。涵盖从理解代码库到生成可验证、可审查差异的完整周期。
适用场景:缺陷修复、功能开发、代码重构、开源贡献,以及任何需要保证正确性和可维护性的代码变更。
工作流程
第一阶段:编码前研究
在理解上下文之前绝不编写代码。 此阶段可避免浪费精力和产生糟糕设计。
1a. 理解项目规范
检查并阅读以下文件(如存在):
- - CONTRIBUTING.md — 贡献指南
- .editorconfig — 格式化规则
- pyproject.toml / package.json / Makefile — 项目配置、代码检查、格式化
- tox.ini / .flake8 / .eslintrc — 代码风格规则
1b. 研究变更区域
- - 阅读将要修改的模块
- 追踪缺陷/功能相关的执行路径
- 理解数据流:输入什么,输出什么
- 记录依赖关系:哪些其他模块与此代码交互
1c. 研究现有测试
- - 找到测试目录结构:tests/、tests/、test/
- 注意测试框架:pytest、jest、go test、JUnit 等
- 研究命名规范:testfeature.py、feature.test.ts、featuretest.go
- 注意使用的夹具/设置模式
- 检查测试工具、工厂函数或模拟对象
1d. 构建心智模型
在编写代码前,明确阐述:
- - 什么需要变更(具体行为)
- 哪里需要变更(文件、函数、类)
- 如何变更(方法)
- 可能出什么问题(边界情况、回归问题)
第二阶段:实现
核心原则
- 1. 最小化、聚焦的变更
- 只修复缺陷/添加功能,不做其他事。
- 避免无关的格式化更改、导入重排或附带重构。
- 如发现其他需要修复的问题,记下来留待单独提交/PR处理。
- 2. 遵循现有模式
- 匹配代码库的风格,而非个人偏好
- 使用相同的命名规范、缩进、注释风格
- 如果项目使用snake_case,不要引入camelCase
- 3. 为非显而易见的逻辑添加注释
- 写为什么的注释,而非是什么的注释
- 解释权衡、变通方案和有意为之的决策
- 4. 为质量而设计
| 原则 | 含义 | 示例 |
|------|------|------|
| 纵深防御 | 多层防护 | 在API+服务+数据库层验证输入 |
| 向后兼容 | 不破坏现有行为 | 添加带默认值的新参数 |
| 优雅降级 | 处理缺失功能 | 平台特定代码安全回退 |
| 可扩展性 | 优先可组合设计 | 插件/中间件优于硬编码分支 |
| 单一职责 | 一个函数只做一件事 | 提取逻辑而非膨胀函数 |
第三阶段:编写测试
测试类别(按顺序实现)
- 1. 修复验证 — 证明缺陷已修复/功能正常工作
testfeaturehandlesnullinput() # 问题中的确切场景
- 2. 边界情况 — 边界条件
testfeaturewithemptystring()
testfeaturewithmaxlength_input()
testfeaturewithspecialcharacters()
- 3. 错误处理 — 无效输入、失败路径
testfeatureraisesoninvalid_type()
testfeaturereturnsnoneonmissingkey()
- 4. 回归测试 — 现有行为保持不变
testexistingbehavior_unchanged()
testothermodulestillworks()
测试编写指南
- - 每个测试一个断言(理想情况下)—— 便于诊断失败
- 描述性名称 — testoauthtokenrefresheswhenexpired 而非 testtoken
- 安排-执行-断言模式:
python
def test_feature():
# 安排
input
data = createtest_data()
# 执行
result = feature(input_data)
# 断言
assert result.status == success
- - 使用夹具实现可复用的设置
- 模拟外部依赖 — 网络调用、文件系统、数据库
- 测试行为而非实现 — 不要断言内部状态
第四阶段:运行测试
渐进式测试策略
bash
1. 先只运行新增/修改的测试(快速反馈)
python -m pytest tests/test
myfeature.py -v --tb=short
或:npm test -- --testPathPattern=my_feature
或:go test ./pkg/my_feature/... -v
2. 运行完整测试模块/目录
python -m pytest tests/ -v --tb=short
3. 运行整个测试套件(提交前)
python -m pytest --tb=short
或:npm test
或:go test ./...
处理测试结果
修复代码,重新运行 |
| 预先存在的失败 | 记录下来,不修复(超出范围) |
| 不稳定测试(随机通过/失败) | 运行3次确认不稳定性,在PR中注明 |
| 无法运行的测试(需要环境/基础设施) | 在PR中注明,说明手动测试的内容 |
第五阶段:审查差异
在提交前,审查差异中的每一行代码。
bash
变更概览
git diff --stat
完整差异
git diff
如果已暂存
git diff --cached
差异审查清单
- - [ ] 每个变更都是有意为之(无意外编辑)
- [ ] 没有遗留的调试打印、TODO注释或临时代码
- [ ] 没有硬编码的密钥、令牌或个人路径
- [ ] 没有无关的格式化更改
- [ ] 所有新函数/类都有适当的文档字符串/注释
- [ ] 测试覆盖范围对变更来说足够充分
- [ ] 新增文件位于正确的目录中
第六阶段:提交
bash
暂存特定文件(绝不使用 git add .)
git add path/to/modified_file.py
git add tests/test
newfeature.py
验证暂存文件
git diff --cached --stat
使用规范消息提交
git commit -m fix(module): 修复内容的简短描述
如果非显而易见,提供更长的原因说明。
关联 #issue_number
提交消息格式
{类型}({范围}): {简洁描述}
{正文:做什么和为什么,而非怎么做}
{页脚:问题引用、测试结果、破坏性变更}
新功能 |
| refactor | 代码重构(无行为变更) |
| test | 仅添加/修复测试 |
| docs | 仅文档变更 |
| chore | 构建/工具/依赖变更 |
输出
- - 功能分支上已提交的代码变更和测试
- 所有测试通过
- 干净、可审查的差异
提示
- - 此技能可独立用于任何开发任务。
- 在贡献流程中,它位于仓库设置之后,并为PR引导提供输入。
- 对于大型功能,以小增量重复第二阶段至第五阶段,而非一次性大变更。
- 与AI结对编程时:在要求AI实现任何内容前,先让AI研究代码库(第一阶段)。