首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

程序员思维体操:TDD修炼手册

  • 25-04-24 19:41
  • 4151
  • 13139
juejin.cn

程序员思维体操:TDD修炼手册

——从"先写代码"到"测试先行"的认知革命

一、重新认识TDD:不仅仅是写测试

什么是TDD(测试驱动开发)
TDD其实很简单,不要看名字很高级复杂,传统开发是直接开发功能,TDD则是先写好测试再开发功能。具体来说:

  1. 开发前先编写描述功能的测试用例
  2. 编写刚好让测试通过的代码
  3. 重构代码使其更优雅,同时保持测试通过

某电商系统开发时,团队在实现优惠券功能前,先写下了这样的测试:

java
代码解读
复制代码
@Test public void 满200减50时支付金额正确() { Coupon coupon = new Coupon("FULL_200_OFF_50"); Order order = new Order(250.00); order.applyCoupon(coupon); assertEquals(200.00, order.getPayAmount()); }

这个测试用例就像施工图纸,明确限定了代码的行为边界。

TDD的设计哲学

  • 需求即测试:将模糊的需求转化为可验证的断言
  • 小步快跑:每次只实现一个微小功能点(如先处理整数相加,再考虑浮点数)
  • 安全网思维:测试集是代码的防弹衣,重构时不再如履薄冰
  • 设计驱动:测试倒逼模块解耦,天然符合SOLID原则

二、TDD实战四部曲:手把手教你开车

1. 红绿灯循环:程序员的新节奏

Step1:红灯阶段(编写失败测试)
在IDE新建文件StringCalculatorTest.java,写下:

java
代码解读
复制代码
@Test public void 空字符串返回0() { assertEquals(0, StringCalculator.add("")); }

此时运行测试必然报错——因为StringCalculator类还不存在。

Step2:绿灯冲刺(最小实现)
创建StringCalculator.java,仅实现能让测试通过的最简代码:

java
代码解读
复制代码
public class StringCalculator { public static int add(String numbers) { return 0; } }

虽然这明显是个"作弊"实现,但此刻测试已变绿。

Step3:重构进化(优化设计)
新增测试输入"1"应返回1,迫使代码升级:

java
代码解读
复制代码
public static int add(String numbers) { return numbers.isEmpty() ? 0 : Integer.parseInt(numbers); }

通过不断添加测试驱动功能迭代,最终实现完整计算器。

2. 测试用例设计心法

案例:开发简易购物车

  • 基础路径:
    java
    代码解读
    复制代码
    @Test public void 添加3件单价100商品总价300() { Cart cart = new Cart(); cart.addItem(new Item("水杯", 100), 3); assertEquals(300, cart.getTotalPrice()); }
  • 边界条件:
    java
    代码解读
    复制代码
    @Test public void 添加0件商品时应抛出异常() { assertThrows(InvalidQuantityException.class, () -> cart.addItem(item, 0)); }
  • 异常场景:
    java
    代码解读
    复制代码
    @Test public void 库存不足时无法添加商品() { Item limitedItem = new Item("限定款", 999, 1); // 最后1件库存 cart.addItem(limitedItem, 1); assertThrows(InventoryShortageException.class, () -> cart.addItem(limitedItem, 1)); }
3. 破解复杂依赖:Mock技术实战

开发支付模块时,如何在不调用真实银行接口的情况下测试?

java
代码解读
复制代码
@Test public void 支付失败时应记录日志() { // 创建模拟支付网关 PaymentGateway mockGateway = mock(PaymentGateway.class); when(mockGateway.pay(any())).thenReturn(false); PaymentService service = new PaymentService(mockGateway); service.processPayment(new Order(100.00)); // 验证是否调用日志记录 verify(logger).error("支付失败,订单号:123"); }

通过Mockito等框架,可以隔离外部系统专注业务逻辑验证。

三、日常训练计划:从菜鸟到TDD武者

1. 新手村任务(第1周)
  • LeetCode特训:
    选择简单题目(如两数之和),强制使用TDD流程:

    1. 先写测试用例
    2. 实现最笨解法
    3. 重构优化时间复杂度
  • 代码考古:
    在GitHub找TDD风格的开源项目(如JUnit自身),观察测试与代码比例

2. 高手试炼(持续进阶)
  • 改造遗留系统:
    选择公司旧模块,为其补充测试覆盖率(从30%提升到70%)
  • 极限挑战:
    尝试用TDD开发贪吃蛇游戏,测试用例包括:
    scss
    代码解读
    复制代码
    @Test public void 蛇头碰到墙时游戏结束() { snake.move(Direction.UP); assertTrue(game.isOver()); }
  • 模式融合:
    在TDD过程中自然引入设计模式,例如:
    scss
    代码解读
    复制代码
    // 测试观察者模式 @Test public void 商品降价时通知所有用户() { Product iphone = new Product("iPhone15", 7999); User zhangsan = new User("张三"); iphone.addObserver(zhangsan); iphone.setPrice(6999); assertTrue(zhangsan.getNotifications().contains("iPhone15降价啦!")); }

四、避坑指南:TDD实践中的暗礁

1. 测试过度症

错误案例:
为Getter/Setter方法编写测试
解决方案:
遵循"测试行为而非实现"原则,只验证业务逻辑

2. 速度焦虑症

典型症状:
认为写测试拖慢进度,退回老路
数据支撑:
谷歌统计显示,TDD初期效率降低20%,但后期维护时间减少50%

3. 用例脆弱症

反面教材:

java
代码解读
复制代码
@Test public void 测试列表顺序() { List list = getData(); assertEquals("苹果", list.get(0)); // 一旦排序逻辑改变就失败 }

改进方案:
断言集合包含元素而非固定顺序:

java
代码解读
复制代码
assertTrue(list.containsAll(Arrays.asList("苹果", "香蕉")));

结语:测试先行的思维革命

当你在设计数据库表结构前先写下UserRegistrationTest,当看到产品文档时脑中自动浮现测试用例树,当代码评审会上能指着测试集说"这就是需求文档"——这一刻,你已完成了从代码工人到软件工匠的蜕变。

TDD是迄今为止最强大的代码质量提升工具,但需要勇气直面初期的不适。

注:本文转载自juejin.cn的用户3539169936215的文章"https://juejin.cn/post/7496345177130532918"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

142
代码人生
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top