code-quality

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Code Quality Standards

代码质量标准

Non-negotiable code quality standards. These are not preferences — they are requirements.

不可妥协的代码质量标准。这些并非偏好选择——而是硬性要求。

Testing Standards

测试标准

The Testing Pyramid

测试金字塔

LayerWhat it TestsSpeedPurpose
Unit TestsIndividual functions/componentsFastTDD lives here. Catches logic errors early.
Integration TestsComponents working togetherMediumCatches connection and data flow issues.
E2E TestsFull user flowsSlowestConfirms the system does the thing.
Human ReviewVisual correctness, UXManualIrreducible quality judgment.
层级测试对象执行速度核心目的
单元测试独立函数/组件极快TDD的核心应用场景,尽早捕获逻辑错误。
集成测试协同工作的组件中等捕获组件间的连接与数据流问题。
端到端(E2E)测试完整用户流程最慢确认系统可完成预期业务功能。
人工评审视觉正确性、用户体验(UX)手动无法替代的主观质量判断环节。

Test-Driven Development (TDD)

测试驱动开发(TDD)

TDD is mandatory at the unit test level:
  1. Tests are written BEFORE implementation — Never implement without a failing test first
  2. Red -> Green -> Refactor is mandatory — No exceptions
  3. Tests define behavior — Implementation serves tests
  4. Small incremental steps — Tiny, safe changes over large speculative edits
  5. Tests are the source of truth — If it's not tested, it doesn't work
When in doubt: Slow down, write the test, make the smallest possible change.
单元测试级别必须遵循TDD:
  1. 先写测试,再实现代码 —— 绝不要在没有失败测试的情况下开始开发
  2. 严格遵循红→绿→重构流程 —— 无例外
  3. 测试定义行为 —— 代码实现为测试服务
  4. 小步增量迭代 —— 优先小幅、安全的变更,而非大规模 speculative 编辑
  5. 测试是事实依据 —— 未经过测试的功能视为不可用
存疑时: 放慢速度,先写测试,再做最小必要变更。

What Makes a Good Test

优质测试的标准

Structure every test as Arrange-Act-Assert:
python
def test_apply_discount_reduces_total():
    # Arrange — set up the scenario
    cart = Cart(items=[Item(price=100)])
    discount = Discount(percent=20)

    # Act — perform the action under test
    cart.apply_discount(discount)

    # Assert — verify the outcome
    assert cart.total == 80
One concept per test. If a test name has "and" in it, split it into two tests.
Name tests to describe behavior, not implementation:
BadGood
test_calculate
test_calculate_total_sums_item_prices
test_error
test_negative_quantity_raises_validation_error
test_user_service
test_deactivated_user_cannot_place_order
Tests must be:
  • Isolated — No test depends on another test's state or execution order
  • Deterministic — Same input, same result. No randomness, no clock dependency, no network calls.
  • Fast — Unit tests run in milliseconds. If they're slow, they're not unit tests.
  • Readable — A failing test name should tell you what broke without reading the test body
所有测试需遵循Arrange-Act-Assert结构:
python
def test_apply_discount_reduces_total():
    # Arrange — set up the scenario
    cart = Cart(items=[Item(price=100)])
    discount = Discount(percent=20)

    # Act — perform the action under test
    cart.apply_discount(discount)

    # Assert — verify the outcome
    assert cart.total == 80
每个测试仅验证一个概念。如果测试名称中包含"and",则拆分为两个独立测试。
测试名称需描述行为,而非实现细节:
不良示例优质示例
test_calculate
test_calculate_total_sums_item_prices
test_error
test_negative_quantity_raises_validation_error
test_user_service
test_deactivated_user_cannot_place_order
测试必须满足:
  • 隔离性 —— 测试之间不依赖彼此的状态或执行顺序
  • 确定性 —— 相同输入必产生相同结果。无随机逻辑、无时钟依赖、无网络调用。
  • 高速性 —— 单元测试需在毫秒级完成。如果执行缓慢,则不属于单元测试范畴。
  • 可读性 —— 失败测试的名称应直接告知问题所在,无需阅读测试代码

Unit Tests

单元测试

  • Foundation of testing
  • Run in milliseconds
  • Test one function/component in isolation
  • Mock external dependencies, not internal logic
  • 测试体系的基础
  • 毫秒级执行
  • 孤立测试单个函数/组件
  • 模拟外部依赖,而非内部逻辑

Integration Tests

集成测试

  • Verify modules work together
  • Use test databases or containers, not mocks
  • Reset state between tests
  • 验证模块间的协同工作能力
  • 使用测试数据库或容器,而非模拟对象
  • 测试间重置状态

E2E Tests

E2E测试

  • Critical user paths only
  • Keep the suite small and focused
  • Accept some flakiness, build in retries
  • 仅覆盖关键用户路径
  • 保持测试套件精简且聚焦
  • 允许一定程度的不稳定,内置重试机制

Human Review

人工评审

  • Does it work correctly?
  • Does it look right?
  • Does it feel good?
  • Is it accessible?

  • 功能是否正常?
  • 视觉呈现是否正确?
  • 使用体验是否流畅?
  • 是否具备可访问性?

Code Structure

代码结构

Early Returns Over Nesting

提前返回替代嵌套

Guard clauses first. Flatten control flow.
Bad — nested, hard to follow:
python
def process(order):
    if order:
        if order.items:
            if order.is_valid:
                return calculate_total(order)
    return None
Good — flat, clear:
python
def process(order):
    if not order:
        return None
    if not order.items:
        return None
    if not order.is_valid:
        return None

    return calculate_total(order)
Max nesting depth: 3 levels. If deeper, extract to a function.
先使用守卫语句,扁平化控制流。
不良示例——嵌套过深,难以阅读:
python
def process(order):
    if order:
        if order.items:
            if order.is_valid:
                return calculate_total(order)
    return None
优质示例——扁平化,逻辑清晰:
python
def process(order):
    if not order:
        return None
    if not order.items:
        return None
    if not order.is_valid:
        return None

    return calculate_total(order)
最大嵌套深度:3层。如果超过,需提取为独立函数。

Function Size

函数规模

A function should do one thing. If you need a comment to separate "sections" inside a function, those sections should be separate functions.
Guidelines:
  • If a function exceeds ~30 lines, look for extraction opportunities
  • If a function takes more than 3-4 parameters, it's probably doing too much
  • If you can't name the function clearly, it has too many responsibilities
一个函数应只做一件事。如果需要用注释分隔函数内的"段落",则这些段落应拆分为独立函数。
指导原则:
  • 如果函数超过约30行,需考虑拆分
  • 如果函数参数超过3-4个,可能承担了过多职责
  • 如果无法清晰命名函数,说明其职责过于繁杂

Single Responsibility

单一职责原则

Every function, class, and module should have one reason to change.
Smell: "This function handles validation AND formatting AND saving." Fix: Three functions —
validate
,
format
,
save
.
每个函数、类和模块都应只有一个变更理由。
坏味道: "这个函数同时处理验证、格式化和存储。" 修复方案: 拆分为三个函数——
validate
format
save

Explicit Over Clever

显式优于巧妙

Readability beats brevity. Separate operations into clear steps.
Bad — clever but hard to debug:
python
names = [u.name for u in users if u.is_active and u.role in allowed]
Good — clear intent, debuggable:
python
active_users = filter_active(users)
authorized_users = filter_by_role(active_users, allowed)
names = extract_names(authorized_users)
When a one-liner requires mental parsing, break it apart. Optimize for the reader, not the writer.

可读性优先于简洁性。将操作拆分为清晰的步骤。
不良示例——看似巧妙但难以调试:
python
names = [u.name for u in users if u.is_active and u.role in allowed]
优质示例——意图清晰,易于调试:
python
active_users = filter_active(users)
authorized_users = filter_by_role(active_users, allowed)
names = extract_names(authorized_users)
当单行代码需要脑力解析时,应将其拆分。为读者优化,而非为编写者优化。

Error Handling

错误处理

Fail Fast

快速失败

Validate inputs at the boundary. Don't let bad data travel deep into the system.
python
def create_user(email, name):
    if not email:
        raise ValidationError("Email is required")
    if not is_valid_email(email):
        raise ValidationError("Invalid email format")

    return save_user(email, name)
在系统边界处验证输入。不要让无效数据深入系统内部。
python
def create_user(email, name):
    if not email:
        raise ValidationError("Email is required")
    if not is_valid_email(email):
        raise ValidationError("Invalid email format")

    return save_user(email, name)

Specific Errors Over Generic

特定错误优于通用错误

Catch what you expect. Re-raise what you don't.
Bad — swallows everything:
python
try:
    do_risky_thing()
except Exception:
    pass
Good — handles what it understands:
python
try:
    do_risky_thing()
except NetworkError:
    return retry()
except ValidationError as e:
    return error_response(e.message)
捕获预期的错误,重新抛出未预期的错误。
不良示例——吞噬所有错误:
python
try:
    do_risky_thing()
except Exception:
    pass
优质示例——仅处理已知错误:
python
try:
    do_risky_thing()
except NetworkError:
    return retry()
except ValidationError as e:
    return error_response(e.message)

Unexpected errors propagate up

未预期的错误向上传播

undefined
undefined

Never Swallow Errors

绝不要吞噬错误

If you catch an error, you must either:
  1. Handle it — take a meaningful recovery action
  2. Log and re-raise it — make the failure visible
  3. Transform it — wrap in a more specific error for the caller
Empty
catch
/
except
blocks are bugs.

如果捕获错误,必须执行以下操作之一:
  1. 处理错误 —— 采取有意义的恢复动作
  2. 记录并重新抛出 —— 让失败可见
  3. 转换错误 —— 包装为调用者更易理解的特定错误
空的
catch
/
except
块属于bug。

Naming Conventions

命名规范

Names must clearly communicate:
  1. Who is acting — The subject performing the action
  2. What action is occurring — The verb describing the behavior
  3. Direction of data or ownership flow — Where things are going to/from
命名必须清晰传达:
  1. 执行者 —— 执行动作的主体
  2. 动作 —— 描述行为的动词
  3. 数据流向或所有权 —— 数据的传递方向或归属

Directional Clarity

流向清晰性

Use prepositions (
to
,
from
,
into
,
onto
) or named parameters.
Bad — Ambiguous:
python
shop.buy_item(item_id, buyer)      # Who is buying?
transfer(amount, account)           # Transfer to or from?
Good — Clear:
python
shop.sell_item_to(item_id, buyer)  # Shop sells TO buyer
shop.sell(item_id, to=buyer)       # Named parameter clarifies
transfer_from(account, amount)      # Direction explicit
account.transfer_to(other, amount)  # Direction in method name
使用介词(
to
from
into
onto
)或命名参数。
不良示例——歧义:
python
shop.buy_item(item_id, buyer)      # 谁在购买?
transfer(amount, account)           # 转入还是转出?
优质示例——清晰:
python
shop.sell_item_to(item_id, buyer)  # 商店售卖给买家
shop.sell(item_id, to=buyer)       # 命名参数明确流向
transfer_from(account, amount)      # 流向明确
account.transfer_to(other, amount)  # 方法名包含流向

The Read-Aloud Test

朗读测试

If a method call doesn't read naturally when spoken aloud, the name is wrong.
python
undefined
如果方法调用朗读起来不自然,说明命名有误。
python
undefined

"shop buy item buyer" — confusing

"shop buy item buyer" —— 混乱

shop.buy_item(item_id, buyer)
shop.buy_item(item_id, buyer)

"shop sell item to buyer" — clear

"shop sell item to buyer" —— 清晰

shop.sell_item_to(item_id, buyer)
undefined
shop.sell_item_to(item_id, buyer)
undefined

Boolean Naming

布尔值命名

Always prefix booleans with
is
,
has
,
should
,
can
,
will
, or
did
:
python
undefined
布尔值必须以
is
has
should
can
will
did
开头:
python
undefined

Bad — ambiguous (is it a noun? a verb? a state?)

不良示例——歧义(是名词?动词?状态?)

active = True permission = True refresh = True
active = True permission = True refresh = True

Good — clearly a yes/no question

优质示例——明确是是非判断

is_active = True has_permission = True should_refresh = True
undefined
is_active = True has_permission = True should_refresh = True
undefined

Naming Patterns

命名模式

PatternUse WhenExample
verb_noun_to(target)
Action flows to target
send_message_to(user)
verb_noun_from(source)
Action flows from source
receive_payment_from(customer)
noun.verb_to(target)
Object performs action toward target
cart.transfer_to(order)
verb(noun, to=target)
Named parameter clarifies
assign(task, to=developer)
模式使用场景示例
verb_noun_to(target)
动作流向目标
send_message_to(user)
verb_noun_from(source)
动作来自源
receive_payment_from(customer)
noun.verb_to(target)
对象执行朝向目标的动作
cart.transfer_to(order)
verb(noun, to=target)
命名参数明确流向
assign(task, to=developer)

Avoid

避坑指南

Don'tInstead
Single letters (except loop
i
,
j
)
Full descriptive name
Abbreviations (
cust_id
)
customer_id
Generic names (
data
,
list
,
temp
)
user_data
,
order_list
Negated booleans (
is_not_disabled
)
is_enabled

不要做替代方案
使用单个字母(循环变量
i
j
除外)
使用完整描述性名称
使用缩写(
cust_id
customer_id
使用通用名称(
data
list
temp
user_data
order_list
使用否定式布尔值(
is_not_disabled
is_enabled

Constants & Clarity

常量与清晰性

No Magic Values

禁止魔法值

Every number and string literal should have a name.
Bad:
python
if retry_count > 3:
    sleep(60)
Good:
python
MAX_RETRIES = 3
RETRY_DELAY_SECONDS = 60

if retry_count > MAX_RETRIES:
    sleep(RETRY_DELAY_SECONDS)
所有数字和字符串字面量都应定义为命名常量。
不良示例:
python
if retry_count > 3:
    sleep(60)
优质示例:
python
MAX_RETRIES = 3
RETRY_DELAY_SECONDS = 60

if retry_count > MAX_RETRIES:
    sleep(RETRY_DELAY_SECONDS)

Boolean Parameters

布尔参数

Boolean arguments hide meaning at the call site.
Bad — what does
True
mean?
python
create_user(data, True, False)
Good — named parameters or options:
python
create_user(data, send_welcome=True, require_verification=False)
If the language doesn't support named parameters, use an options object/struct.

布尔参数会隐藏调用处的含义。
不良示例——
True
的含义是什么?
python
create_user(data, True, False)
优质示例——使用命名参数或选项对象:
python
create_user(data, send_welcome=True, require_verification=False)
如果语言不支持命名参数,使用选项对象/结构体。

Documentation

文档

Docstrings

文档字符串(Docstrings)

Docstrings are living documentation. Public APIs must be self-explanatory without reading implementation.
文档字符串是活文档。公共API必须无需阅读实现代码即可理解其用法。

Required Elements

必填元素

Every public function, method, and class must include:
  1. Purpose — What it does (one line)
  2. Parameters — Each parameter with type and meaning
  3. Returns — What is returned and when
  4. Side effects — Any state changes, I/O, or mutations
  5. Errors — What exceptions/errors can occur
  6. Examples — Realistic usage showing common cases
每个公共函数、方法和类必须包含:
  1. 用途 —— 功能概述(一行)
  2. 参数 —— 每个参数的类型与含义
  3. 返回值 —— 返回内容及场景
  4. 副作用 —— 任何状态变更、I/O操作或数据修改
  5. 错误 —— 可能抛出的异常/错误类型
  6. 示例 —— 展示常见用法的真实场景

Example Docstring

文档字符串示例

python
def sell_item_to(self, item_id: str, buyer: Customer) -> Receipt:
    """Sell an item from shop inventory to a customer.

    Transfers ownership of the item from the shop to the buyer,
    processes payment, and updates inventory.

    Args:
        item_id: Unique identifier of the item to sell.
        buyer: Customer purchasing the item. Must have sufficient balance.

    Returns:
        Receipt containing transaction details and timestamp.

    Raises:
        ItemNotFoundError: If item_id doesn't exist in inventory.
        InsufficientBalanceError: If buyer can't afford the item.
        ItemAlreadySoldError: If item was sold between check and purchase.

    Examples:
        Basic sale:
        >>> shop = Shop(inventory=[item])
        >>> buyer = Customer(balance=100)
        >>> receipt = shop.sell_item_to(item.id, buyer)
        >>> assert receipt.amount == item.price
        >>> assert item.id not in shop.inventory

        Handling insufficient balance:
        >>> poor_buyer = Customer(balance=0)
        >>> shop.sell_item_to(item.id, poor_buyer)
        Raises InsufficientBalanceError
    """
python
def sell_item_to(self, item_id: str, buyer: Customer) -> Receipt:
    """Sell an item from shop inventory to a customer.

    Transfers ownership of the item from the shop to the buyer,
    processes payment, and updates inventory.

    Args:
        item_id: Unique identifier of the item to sell.
        buyer: Customer purchasing the item. Must have sufficient balance.

    Returns:
        Receipt containing transaction details and timestamp.

    Raises:
        ItemNotFoundError: If item_id doesn't exist in inventory.
        InsufficientBalanceError: If buyer can't afford the item.
        ItemAlreadySoldError: If item was sold between check and purchase.

    Examples:
        Basic sale:
        >>> shop = Shop(inventory=[item])
        >>> buyer = Customer(balance=100)
        >>> receipt = shop.sell_item_to(item.id, buyer)
        >>> assert receipt.amount == item.price
        >>> assert item.id not in shop.inventory

        Handling insufficient balance:
        >>> poor_buyer = Customer(balance=0)
        >>> shop.sell_item_to(item.id, poor_buyer)
        Raises InsufficientBalanceError
    """

Docstring Rules

文档字符串规则

  • Examples should mirror actual test scenarios
  • Update docstrings when behavior changes
  • Treat docstrings as first-class code, not decoration
  • 示例应与实际测试场景一致
  • 当行为变更时更新文档字符串
  • 将文档字符串视为一等公民代码,而非装饰

Comments

注释

Do CommentDon't Comment
Why — intent, business reason, non-obvious contextWhat — the code already says this
Non-obvious gotchas or edge casesObvious operations
Complex algorithm summariesBad code to explain it (fix the code instead)
TODO with ticket/issue referenceTODO without context
If you need a comment to explain what code does, the code should be clearer. Rename variables, extract functions, simplify logic — then the comment becomes unnecessary.

应注释内容不应注释内容
原因 —— 意图、业务背景、非显而易见的上下文内容 —— 代码本身已说明
非显而易见的陷阱或边缘情况明显的操作
复杂算法的摘要用注释解释坏代码(应直接修复代码)
包含工单/问题引用的TODO无上下文的TODO
如果需要注释解释代码的功能,说明代码应更清晰。重命名变量、提取函数、简化逻辑——之后注释就不再必要了。

Quick Reference

快速检查清单

  • Tests written BEFORE implementation
  • Red -> Green -> Refactor followed
  • Each test has one concept, Arrange-Act-Assert structure
  • Tests are isolated, deterministic, fast
  • All tests pass, edge cases covered
  • Functions are short, single-responsibility
  • Max 3 levels of nesting, early returns used
  • Errors fail fast at boundaries with specific types
  • No empty catch/except blocks
  • Names pass the read-aloud test
  • Directional clarity in method names (to/from)
  • Booleans prefixed with is/has/should/can
  • No abbreviations, no generic names
  • No magic numbers or strings — constants extracted
  • Boolean parameters use named args or options
  • All public APIs have complete docstrings
  • Comments explain why, not what

  • 先写测试,再实现代码
  • 遵循红→绿→重构流程
  • 每个测试仅验证一个概念,采用Arrange-Act-Assert结构
  • 测试具备隔离性、确定性、高速性
  • 所有测试通过,覆盖边缘场景
  • 函数简短,符合单一职责
  • 最大嵌套深度3层,使用提前返回
  • 错误在边界处快速失败,使用特定错误类型
  • 无空的catch/except块
  • 命名通过朗读测试
  • 方法名具备流向清晰性(to/from)
  • 布尔值以is/has/should/can开头
  • 无缩写、无通用名称
  • 无魔法数字或字符串——已提取为常量
  • 布尔参数使用命名参数或选项对象
  • 所有公共API具备完整文档字符串
  • 注释解释原因,而非内容

References

参考资料

  • references/testing-reference.md
    — Testing pyramid deep-dive, mocking guidelines, anti-patterns
  • references/naming-reference.md
    — Complete naming conventions, abbreviation rules, domain naming
  • references/error-handling-reference.md
    — Error hierarchies, retry/fallback patterns, error boundaries
  • references/testing-reference.md
    —— 测试金字塔深度解析、模拟对象指南、反模式
  • references/naming-reference.md
    —— 完整命名规范、缩写规则、领域命名
  • references/error-handling-reference.md
    —— 错误层级、重试/降级模式、错误边界

Assets

资源文件

  • assets/tdd-checklist.md
    — Step-by-step TDD workflow checklist
  • assets/docstring-templates.md
    — Copy-paste docstring templates (Python, JS/TS, C#, Rust, Go)
  • assets/code-review-checklist.md
    — Comprehensive code review checklist
  • assets/tdd-checklist.md
    —— 分步TDD工作流程检查清单
  • assets/docstring-templates.md
    —— 可直接复制的文档字符串模板(Python、JS/TS、C#、Rust、Go)
  • assets/code-review-checklist.md
    —— 全面的代码评审检查清单

Scripts

脚本工具

  • scripts/check_naming.py
    — Validate naming conventions across any codebase
  • scripts/check_complexity.py
    — Check function length, nesting depth, parameter count
  • scripts/check_naming.py
    —— 验证任意代码库的命名规范
  • scripts/check_complexity.py
    —— 检查函数长度、嵌套深度、参数数量