You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不知代码实现逻辑时,如何践行测试驱动开发(TDD)?

TDD实践困境:React图片标记器开发的解决方案分析

问题场景

我有一年TDD实践经验,一直坚持测试行为而非实现。现在要开发React的「图片标记器」功能:用户点击图片,若点击坐标匹配特定人物/物体的坐标,返回true。已知可能用到getBoundingClientRect但不熟悉用法,陷入循环——TDD要求先写失败测试,但完全不知道怎么写测试和验证目标,不敢无测试实验代码,导致停滞。

对四个方案的反馈

方案1:创建独立的「playground」文件进行实验

这是非常合理且专业的做法。TDD的核心是驱动生产代码的开发,但实验性代码不属于生产代码范畴。你可以在项目外或项目内单独建playground/目录,专门测试getBoundingClientRect的用法、坐标计算逻辑,甚至快速搭一个极简React组件模拟点击场景。这种实验不违反TDD原则,只是帮你理清技术细节,为后续编写生产代码的测试打基础。

  • 优势:完全隔离生产代码,不会污染主分支;快速验证技术可行性,帮你明确测试的验证逻辑。

方案2:创建实验分支编码后,回主分支按TDD重写

这个方案可行,但效率略低。创建实验分支探索功能实现没问题,但删除分支后在主分支重写属于重复劳动。可以调整为:在实验分支完成技术验证后,直接基于已有的理解在该分支补写测试,确保测试覆盖行为逻辑后再合并到主分支——只要最终合并的代码符合「测试定义行为,代码满足测试」的TDD核心,就不算违背原则,不必纠结于绝对的提交顺序。

  • 注意:绝对不能把无测试的实验代码直接合并到主分支,必须补全测试后再合并。

方案3:放弃TDD先写代码再补测试

这是最不推荐的做法。一旦打破「测试先于代码」的习惯,很容易陷入「代码写完懒得补测试」的陷阱,违背你坚持TDD的初衷。而且先写代码再补测试,容易变成测试实现而非行为——你会不自觉地跟着已写的代码逻辑写测试,而非从用户行为出发定义预期。

方案4:先写空测试使其编译失败,编写代码后再补充测试内容

这个方案可作为过渡手段,但不能滥用。空测试能帮你先搭建测试框架的结构,比如:

test('点击图片中人物区域返回true', () => {
  // TODO: 补充测试逻辑
});

但关键是,你不能先写生产代码再补测试内容,而是要在补测试时先明确用户行为的预期(比如「点击坐标(100,200)属于人物区域时返回true」),再基于这个预期写生产代码。如果只是为了编译通过写空测试,之后直接写代码再补测试,本质还是方案3的变种,违背TDD原则。

整体建议

  1. 优先用方案1做技术验证:先在playground里搞清楚getBoundingClientRect返回的坐标结构、如何将点击事件的clientX/clientY与目标区域坐标做对比。比如写一个极简脚本:
const img = document.createElement('img');
img.src = 'test.jpg';
img.style.width = '500px';
document.body.appendChild(img);
img.onload = () => {
  const rect = img.getBoundingClientRect();
  console.log(rect); // 查看坐标信息
  // 模拟点击坐标
  const clickX = rect.left + 100;
  const clickY = rect.top + 200;
  // 定义目标区域范围
  const isInTarget = clickX > rect.left + 50 && clickX < rect.left + 150 
                  && clickY > rect.top + 150 && clickY < rect.top + 250;
  console.log(isInTarget);
};

搞懂这些细节后,你就能明确测试的预期:「当点击事件的坐标落在目标区域范围内时,组件返回true」。

  1. 从最小单元开始写测试:不要一开始就想写完整的组件测试,先拆分纯逻辑单元。比如先测试「给定目标区域坐标和点击坐标,判断是否匹配的函数返回正确结果」——这个函数不依赖React,纯逻辑,很容易写测试:
test('点击坐标在目标区域内返回true', () => {
  const targetArea = { left: 50, top: 150, right: 150, bottom: 250 };
  const clickCoords = { x: 100, y: 200 };
  expect(isClickInTarget(clickCoords, targetArea)).toBe(true);
});

test('点击坐标在目标区域外返回false', () => {
  const targetArea = { left: 50, top: 150, right: 150, bottom: 250 };
  const clickCoords = { x: 200, y: 300 };
  expect(isClickInTarget(clickCoords, targetArea)).toBe(false);
});

用TDD完成这个纯逻辑函数后,再集成到React组件中,测试组件的点击行为(比如模拟点击图片的某个位置,验证组件是否返回true)。

  1. 不要纠结绝对的「测试先于代码」:TDD的核心是用测试定义行为,再实现代码满足测试,而非机械地严格执行「先写测试再写代码」的步骤。如果某个技术细节完全不了解,先做实验性探索是合理的,这不属于生产代码的开发流程,不会违背TDD的初衷。

内容的提问来源于stack exchange,提问作者ElMoscaviador

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:32:37