Token导航 LogoToken导航

Agent Skill · 研究检索

bookforge-build-refactoring-test-suite(bookforge 构建重构测试套件)

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

bookforge-build-refactoring-test-suite 是研究检索类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为调用外部服务;许可证为 MIT-0,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 24,110。

总安装 4,093周安装 164GitHub Stars 公开资料未说明下载 1,325核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
1.0.0

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:bookforge-build-refactoring-test-suite(bookforge 构建重构测试套件)
来源仓库:https://github.com/quochungto/bookforge-build-refactoring-test-suite
安装命令:
openclaw skills install bookforge-build-refactoring-test-suite
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install bookforge-build-refactoring-test-suite

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于在重构前构建足够的自动化测试套件,保障变更安全并提供回归验证能力。适用于 OpenClaw 环境中的测试设计与回归验证场景。应用六步顺序流程:测试类→夹具→正常等确保覆盖关键模块。使用时需确认现有代码结构和测试框架,避免误改真实逻辑。涉及浏览器或外部服务时应区分本地模拟与生产环境,优先覆盖高风险模块。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install bookforge-build-refactoring-test-suite;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要调用外部服务,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

bookforge-build-refactoring-test-suite 怎么安装?

在终端执行 openclaw skills install bookforge-build-refactoring-test-suite。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

bookforge-build-refactoring-test-suite 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

bookforge-build-refactoring-test-suite 需要什么权限?

权限级别是调用外部服务。该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

bookforge-build-refactoring-test-suite 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

bookforge-build-refactoring-test-suite 用的人多吗?

公开数据是累计安装 4,093 次,近一周安装 164 次,下载 1,325 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

bookforge-build-refactoring-test-suite 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
bookforge-build-refactoring-test-suite

bookforge 构建重构测试套件 · 本页

4,093—调用外部服务MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
build-refactoring-test-suite
description
Build a sufficient automated test suite before refactoring existing code by applying a 6-step sequential construction workflow (test class → fixture → normal behavior → boundary conditions → expected errors → green-suite gate) and a bug-fix variant (write failing test first → reproduce → fix → verify green). Use this skill when you are about to refactor a class or module that lacks tests, when a bug report arrives and you need to pin it down before fixing it, when you want to establish the compile-and-test gate that makes every subsequent refactoring step safe to revert, or when you need to assess whether an existing test suite is adequate to protect a planned refactoring.
version
1.0.0
homepage
https://github.com/bookforge-ai/bookforge-skills/tree/main/books/refactoring/skills/build-refactoring-test-suite
metadata
{"openclaw":{"emoji":"🧪","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status
draft
source-books
title
Refactoring: Improving the Design of Existing Code
authors
["Martin Fowler"]
chapters
[4]
tags
[refactoring, testing, code-quality]
depends-on
[]
execution
tier
2
mode
hybrid
inputs
description
A class, module, or file to be refactored, with or without existing tests.
tools-required
[Read, Write, Bash]
tools-optional
[]
mcps-required
[]
environment
Working codebase with a test runner available. Output: a runnable test file that passes green, covering normal behavior, boundary conditions, and expected errors for the code under refactoring.
discovery
goal
Produce a fast, self-checking test suite that turns green before any refactoring step begins and re-runs in seconds after every atomic change.
tasks
audience
developers, engineers, anyone refactoring existing production code without adequate test coverage
when_to_use
When a class or module needs to be refactored and does not yet have a test suite sufficient to detect regressions after each atomic change
environment
Existing codebase. The code under refactoring should be readable. A test runner (any language) must be available.
quality
placeholder

Build Refactoring Test Suite

When to Use

You are about to refactor code — extracting methods, moving fields, changing conditionals — and one of these is true:

  • The code has no tests at all
  • The existing tests are incomplete, untargeted, or only cover happy paths
  • A bug has been reported and you need to pin it down before fixing and refactoring around it
  • You are inheriting code from someone else and want a safety net before touching anything

This is the Level 0 foundation skill: every other refactoring mechanic in Fowler's catalog assumes this suite exists. Without it, you are refactoring blind. With it, every subsequent step is reversible — if a test turns red, you revert and try smaller steps.

The core pattern: build a self-checking test suite that runs in seconds, covers the code you are about to change, and can answer one question without human inspection: "Did I break anything?"

Before starting, confirm you have:

  • Read access to the class or module being refactored
  • A test runner installed for the language (pytest, JUnit, RSpec, Vitest, go test, etc.)
  • The ability to run the test suite from the command line

Context and Input Gathering

Required Context

  • Target code: The class, module, or file to be refactored. Read it fully before writing any tests.
  • Language and test framework: Identify from the project structure (e.g., pyproject.toml, package.json, pom.xml, go.mod). Use the framework already in place — do not introduce a new one.
  • Existing tests: Check for any test files that already cover the target. Run them first. If they all pass, extend rather than replace.

Observable Context

Scan the target code for:

  • Public interface: Every public method, function, or exported symbol is a testing target. Private internals are not — test through the public interface only.
  • Inputs and outputs: What does each method take in and return? These define what to assert.
  • Error conditions: What inputs should raise exceptions, return error codes, or produce empty results? These drive the error-path tests.
  • State mutations: Does the class modify shared state? Fixtures must initialize and tear down that state per-test.
  • External dependencies: Databases, files, network calls. These need either real test fixtures or test doubles (mocks/stubs). Prefer real fixtures for refactoring — mocks can hide regressions.

Default Assumptions

  • If no test framework exists → pick the language's idiomatic standard (pytest for Python, JUnit for Java, Vitest for TypeScript, etc.)
  • If the code reads external files → create small, dedicated test data files in a testdata/ or fixtures/ directory
  • If the code has database calls → prefer an in-memory or test-mode database over mocking; mocks test the mock, not the code
  • If tests already exist and pass → run them first, then add missing coverage; do not re-implement passing tests

Sufficiency Check

You are ready to start when:

  1. You can read the target class/module completely
  2. You know which test framework is in use
  3. You know at least three things the code is supposed to do (its public contract)

If you cannot determine what the code is supposed to do (no comments, no documentation, unclear naming), read the calling code or integration tests first to reconstruct the intended behavior before writing unit tests.


Process

Step 1 — Create the Test Class/File

Create a dedicated test file for the code under refactoring. Place it where the project's test convention dictates (e.g., tests/test_order.py, src/__tests__/Order.test.ts, OrderTest.java).

Why: Each class under test needs its own test container. Mixing multiple classes into one test file makes isolation harder and failure messages harder to read. Using the project's existing naming convention ensures the test runner discovers the file automatically.

Minimal structure:

# Python
class TestOrder:
    pass

# Java
class OrderTest extends TestCase { }

# TypeScript
describe('Order', () => { })

# Go
func TestOrder(t *testing.T) { }

Run the empty test file immediately to confirm the runner finds and executes it without errors.


Step 2 — Implement Setup and Teardown Fixtures

Before writing any test methods, define the shared state that every test will need. The test framework's setUp/beforeEach/setup hook runs before each test; tearDown/afterEach/cleanup runs after.

Why: Each test must be fully isolated — it must not depend on execution order, and it must not leave side effects that corrupt the next test. Setup creates a fresh environment; teardown cleans up resources (open files, database connections, temp files). Without this isolation, a failure in test 3 can cause test 4 to fail for unrelated reasons, making debugging misleading.

Guidelines:

  • Initialize only what is shared across most tests in the fixture. Test-specific state belongs in the test method itself.
  • If setup can fail (file not found, connection refused), let the error propagate — a setup failure is a hard stop, not a test failure.
  • If teardown involves resource release (closing files, dropping test tables), do it unconditionally — use finally blocks or the framework's guaranteed cleanup mechanism.
# Python example
class TestFileProcessor:
    def setup_method(self):
        self.input_file = open("testdata/sample.txt", "r")

    def teardown_method(self):
        self.input_file.close()

Step 3 — Write Tests for Normal / Expected Behavior

For each public method, test the central, intended behavior first — the happy path. Ask: "What is this method supposed to do when given valid, typical input?"

Why: Start with normal behavior so you confirm the code works correctly before probing its edges. If normal behavior tests fail, the code is broken before you even touch it — that is useful information and must be resolved before any refactoring begins.

Rules:

  • One behavior per test method. Do not write omnibus tests that check five things in sequence — when one assertion fails, you cannot tell which behavior broke.
  • Name tests descriptively: test_read_returns_correct_character, not test1. Descriptive names are the failure message.
  • Assert the specific output, not just "no exception was raised." Confirm the actual value.
  • Write the test, then verify it can fail: temporarily corrupt the assertion value (e.g., assert 'x' == result instead of 'd' == result). If it does not fail, the test is not testing what you think.
def test_read_returns_correct_character(self):
    # advance past the first three characters
    for _ in range(3):
        self.input_file.read(1)
    ch = self.input_file.read(1)
    assert ch == 'd'  # fourth character in the test file

Step 4 — Add Boundary Condition Tests

After normal behavior is covered, identify the boundaries where behavior could change or break. Boundary conditions are the most productive place to find bugs.

Why: Most bugs hide at the edges — the first item, the last item, the empty collection, the zero value, the maximum value. Fowler calls this "playing the part of an enemy to your own code" — actively trying to find the conditions under which the code will fail, rather than confirming it works for typical input.

Common boundary categories:

CategoryExamples
Sequence edgesFirst element, last element, element after the last
Empty inputsEmpty string, empty list, empty file, zero-length collection
Zero / null valuesZero quantity, null reference, None, empty optional
Maximum / minimum valuesInteger overflow boundary, max string length, single-item list
Repeated callsReading past end-of-file twice, calling close twice

For each boundary, write a separate test method. Add a descriptive message to assertions so that when a boundary test fails, the output tells you which boundary broke.

def test_read_at_end_of_file_returns_minus_one(self):
    # consume all 141 characters
    for _ in range(141):
        self.input_file.read(1)
    result = self.input_file.read(1)
    assert result == -1, "read at end of file should return -1"

def test_read_from_empty_file_returns_minus_one(self):
    empty = open("testdata/empty.txt", "r")
    result = empty.read(1)
    empty.close()
    assert result == -1, "read from empty file should return -1"

Step 5 — Write Tests for Expected Errors and Exceptions

Test that error conditions produce the correct error, not just that they do not crash silently. If the code's contract says "raises ValueError on negative input" or "raises IOError if the stream is closed," write a test that verifies exactly that.

Why: Errors are part of the public contract. Failing to raise the expected error — or raising the wrong one — is a bug. These tests also protect against future refactoring silently swallowing exceptions.

Pattern:

  • Close the resource intentionally, then attempt an operation — expect the specific error.
  • Use the framework's pytest.raises, assertRaises, or expect { }.to raise_error idiom.
  • If the test body completes without the expected error, force an explicit failure: fail("expected error was not raised").
def test_read_after_close_raises_io_error(self):
    self.input_file.close()
    with pytest.raises(IOError):
        self.input_file.read(1)
    # if no IOError is raised, pytest.raises will fail the test automatically

Step 6 — Run the Full Suite: Green Gate

Run the entire test suite. All tests must pass — green — before any refactoring step begins.

Why: This is the precondition that makes refactoring safe. If the suite is red before you start, you do not know whether a subsequent red result was caused by your change or by a pre-existing bug. You must start from a known-good baseline.

What to do if tests are red before you start:

  1. Do not begin refactoring yet.
  2. Determine whether the failure is a test bug (wrong assertion) or a production bug.
  3. If it is a production bug, decide: fix it first, or document it as a known failure and exclude that test from the baseline. Do not silently ignore red tests.
  4. Once all tests pass (or excluded failures are documented), the green gate is established.

The compile-and-test gate (applies to every subsequent step): Once the suite is green and refactoring begins, apply this gate after every single atomic change — not after a batch of changes:

make one atomic change → compile/lint → run test suite
  green → continue to next change
  red   → revert immediately, try a smaller step

"Atomic" means the smallest possible change that can be independently compiled and tested: extract one method, rename one variable, move one field. Never accumulate multiple changes before testing. Small steps mean small reverting cost.

If a language has a compiler, compile first — compilation errors caught before test execution are faster feedback than test failures.


Bug-Fix Variant: Test-First Bug Reproduction

When fixing a bug rather than refactoring, use this variant workflow:

  1. Write a failing test that reproduces the bug. Do this before touching production code. The test should fail because the bug exists.
  2. Confirm the test fails. Run it. If it passes, the test is wrong — it is not actually testing the buggy behavior.
  3. Fix the production code to make the test pass.
  4. Run the full suite. All tests should be green. If new failures appeared, your fix introduced a regression.

Why test first for bugs: Writing the test first forces you to understand exactly what the bug is, not approximately what it is. It also prevents you from accidentally fixing a different problem and convincing yourself the bug is gone. And the test permanently guards against the same bug recurring.

When a bug report arrives:

  • Start by writing a unit test that exposes the bug, not by opening the source file.
  • If you need multiple tests to narrow the scope of the bug (to rule out related failures), write all of them before fixing anything.
  • The unit tests become the regression suite for this bug forever.

Test Adequacy Criteria

A test suite is sufficient for refactoring when it satisfies all four of these criteria:

CriterionWhat to Check
Normal behavior coveredEvery public method has at least one test for its primary intended behavior
Boundaries coveredEach method has tests for: empty input, first/last element, value after the last, zero/null values
Error paths coveredEvery documented error condition or exception has a test that verifies it is raised correctly
Fast enough to run after every stepThe full suite completes in under 30 seconds. If it takes longer, it will not be run frequently enough

What you do not need:

  • 100% branch coverage — Fowler explicitly rejects coverage targets as the goal. The goal is testing where the risk is.
  • Tests for simple accessors (getters/setters that do nothing but read/write a field) — too simple to fail.
  • Tests for every combination in a class hierarchy — test each alternative independently; only test combinations where the alternatives interact in complex ways.

Fowler's practical rule: Test the areas you are most worried about going wrong. Concentrate effort where complexity is highest and where bugs would be hardest to find manually. It is better to run incomplete tests than to have no tests because a complete suite felt impossible to write.


Key Principles

1. Tests must be self-checking. Tests that print output to the console for a human to inspect are not self-checking. Every assertion must be evaluated by the framework automatically. The only acceptable output is a pass/fail signal — ideally a progress bar that turns red on failure.

2. Tests must be fast. Slow tests do not get run. If the suite takes more than 30 seconds, developers will batch changes and run tests infrequently. Infrequent testing means bugs accumulate between runs, making them harder to isolate. For refactoring specifically, tests must be fast enough to run after every single atomic step.

3. Each test must be isolated. A test must not depend on the results of any other test. Execution order must not matter. Use setup/teardown to ensure each test starts from an identical, known state.

4. Verify that tests can fail. When you write a test, temporarily insert a wrong value into the assertion. If the test does not turn red, it is not exercising what you think. A test that cannot fail is not a test — it is false confidence.

5. Incomplete tests beat no tests. The most common failure mode is paralysis: "I can't test everything perfectly, so I won't test anything." Write the tests for the risky areas first. Run them. An imperfect suite that runs frequently is vastly more valuable than a theoretically complete suite that never gets written.

6. The compile-and-test gate is non-negotiable. Every atomic refactoring step ends with: compile + run suite. Red = revert. No exceptions. This is what makes refactoring safe to do in a production codebase.


Examples

Example 1: Adding tests before extracting methods from a billing class

Situation: You want to decompose a 200-line calculate_invoice() method into smaller methods but there are no tests.

Setup fixture: Create an Invoice object with known line items and tax rates. Normal behavior tests: Assert that calculate_invoice() returns the correct total for a standard order. Boundary tests: Empty order (zero line items), single item, order with a discount applied to zero-priced items. Error tests: Negative quantity raises ValueError, unknown product code raises KeyError. Green gate: All pass. Now decompose calculate_invoice() one extracted method at a time, running after each extraction.


Example 2: Bug-fix variant for a reported pricing error

Situation: A bug report says orders over $1,000 are applying the discount twice.

Step 1 — Write failing test:

def test_discount_applied_once_for_large_order(self):
    order = Order(items=[Item("product-A", quantity=10, unit_price=150)])  # total = $1,500
    assert order.total_price() == 1350.00  # 10% discount applied once

Step 2 — Run it. It fails (returns 1215.00 — discount applied twice). Good. The test reproduces the bug. Step 3 — Fix the discount logic. Step 4 — Run full suite. All green including the new test. Bug is fixed and regression-protected.


Example 3: Assessing an existing test suite before a large refactoring

Situation: A module has 12 tests. You want to refactor its data model.

Audit checklist:

  • [ ] Does every public method have at least one test? — Check: 3 public methods, 12 tests → appears covered
  • [ ] Are boundaries tested? — Check: no test for empty input, no test for maximum collection size → gap found
  • [ ] Are error paths tested? — Check: no test for invalid state transition → gap found
  • [ ] Does the suite run in under 30 seconds? — Check: 4.2 seconds → acceptable

Action: Add boundary and error path tests. Run. Green. Now proceed with the refactoring.


License

This skill is licensed under CC-BY-SA-4.0. Source: BookForge — Refactoring: Improving the Design of Existing Code by Martin Fowler.

Related BookForge Skills

  • refactoring-readiness-assessment — Assess whether code is ready to refactor
  • code-smell-diagnosis — Identify which smells to address first
  • method-decomposition-refactoring — Apply once this test suite is green

Browse more BookForge skills: bookforge-skills

平台分布

OpenClaw

94.1%
按下载量换算1,247

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

调用外部服务

该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

安装前确认

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

继续浏览同类 Skills