程序員思維體操:TDD修煉手冊

程序員思維體操:TDD修煉手冊

——從"先寫代碼"到"測試先行"的認知革命

一、重新認識TDD:不僅僅是寫測試

什么是TDD(測試驅動開發)
TDD其實很簡單,不要看名字很高級復雜,傳統開發是直接開發功能,TDD則是先寫好測試再開發功能。具體來說:

  1. 開發前先編寫描述功能的測試用例
  2. 編寫剛好讓測試通過的代碼
  3. 重構代碼使其更優雅,同時保持測試通過

某電商系統開發時,團隊在實現優惠券功能前,先寫下了這樣的測試:

@Test  
public void 滿20050時支付金額正確() {  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,寫下:

@Test  
public void 空字符串返回0() {  assertEquals(0, StringCalculator.add(""));  
}  

此時運行測試必然報錯——因為StringCalculator類還不存在。

Step2:綠燈沖刺(最小實現)
創建StringCalculator.java,僅實現能讓測試通過的最簡代碼:

public class StringCalculator {  public static int add(String numbers) {  return 0;  }  
}  

雖然這明顯是個"作弊"實現,但此刻測試已變綠。

Step3:重構進化(優化設計)
新增測試輸入"1"應返回1,迫使代碼升級:

public static int add(String numbers) {  return numbers.isEmpty() ? 0 : Integer.parseInt(numbers);  
}  

通過不斷添加測試驅動功能迭代,最終實現完整計算器。

2. 測試用例設計心法

案例:開發簡易購物車

  • 基礎路徑
    @Test  
    public void 添加3件單價100商品總價300() {  Cart cart = new Cart();  cart.addItem(new Item("水杯", 100), 3);  assertEquals(300, cart.getTotalPrice());  
    }  
    
  • 邊界條件
    @Test  
    public void 添加0件商品時應拋出異常() {  assertThrows(InvalidQuantityException.class,  () -> cart.addItem(item, 0));  
    }  
    
  • 異常場景
    @Test  
    public void 庫存不足時無法添加商品() {  Item limitedItem = new Item("限定款", 999, 1);  // 最后1件庫存  cart.addItem(limitedItem, 1);  assertThrows(InventoryShortageException.class,  () -> cart.addItem(limitedItem, 1));  
    }  
    
3. 破解復雜依賴:Mock技術實戰

開發支付模塊時,如何在不調用真實銀行接口的情況下測試?

@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開發貪吃蛇游戲,測試用例包括:
    @Test  
    public void 蛇頭碰到墻時游戲結束() {  snake.move(Direction.UP);  assertTrue(game.isOver());  
    }  
    
  • 模式融合
    在TDD過程中自然引入設計模式,例如:
    // 測試觀察者模式  
    @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. 用例脆弱癥

反面教材

@Test  
public void 測試列表順序() {  List<String> list = getData();  assertEquals("蘋果", list.get(0));  // 一旦排序邏輯改變就失敗  
}  

改進方案
斷言集合包含元素而非固定順序:

assertTrue(list.containsAll(Arrays.asList("蘋果", "香蕉")));  

結語:測試先行的思維革命

當你在設計數據庫表結構前先寫下UserRegistrationTest,當看到產品文檔時腦中自動浮現測試用例樹,當代碼評審會上能指著測試集說"這就是需求文檔"——這一刻,你已完成了從代碼工人到軟件工匠的蛻變。

TDD是迄今為止最強大的代碼質量提升工具,但需要勇氣直面初期的不適。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/902939.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902939.shtml
英文地址,請注明出處:http://en.pswp.cn/news/902939.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

建筑節能成發展焦點,樓宇自控應用范圍持續擴大

在全球能源危機日益嚴峻、環保意識不斷增強的大環境下&#xff0c;建筑節能已成為建筑行業發展的核心議題。從大型商業綜合體到普通住宅&#xff0c;從公共建筑到工業廠房&#xff0c;節能需求貫穿建筑全生命周期。而樓宇自控系統憑借其對建筑設備的智能化管理和精準調控能力&a…

嵌入式軟件--stm32 DAY 3

0、GPIO回顧 GPIO&#xff0c;通用型輸入輸出&#xff0c;控制stm32輸入輸出的引腳&#xff0c;統稱GPIO。 主功能是默認的功能 復用的功能在芯片里都是由連線的&#xff0c;有聯系才能復用。所以GPIO引腳能復用的功能只能是它默認復用功能和重定義功能。一般都使用默認功能…

點云從入門到精通技術詳解100篇-基于二次誤差和高斯混合模型的點云配準算法

目錄 知識儲備 結合二次誤差度量與高斯混合模型的點云配準 算法核心創新點: 關鍵參數說明: 性能優化建議: 前言 國內外研究現狀 全局配準算法的國內外研究 局部配準算法的國內外研究 2 點云配準相關概念與方法 2.1 什么是點云配準 2.2 點云的獲取及點云主要數據…

linux系統問題雜談

1.配置好anaconda之后&#xff0c;在一個終端中編輯好環境變量之后能夠正常使用conda命令&#xff0c;但是新打開一個中斷使用conda命令報錯"無法識別conda"。 原因&#xff1a;使用“export PATH"/home/username/anaconda3/bin:$PATH"命令&#xff0c;臨…

【中級軟件設計師】函數調用 —— 傳值調用和傳地址調用 (附軟考真題)

【中級軟件設計師】函數調用 —— 傳值調用和傳地址調用 (附軟考真題) 目錄 【中級軟件設計師】函數調用 —— 傳值調用和傳地址調用 (附軟考真題)一、歷年真題二、考點&#xff1a;函數調用 —— 傳值調用和傳地址調用&#x1f53a;1、傳值調用&#x1f53a;2、傳引用(地址)調…

Spring Cloud Gateway 如何將請求分發到各個服務

前言 在微服務架構中&#xff0c;API 網關&#xff08;API Gateway&#xff09;扮演著非常重要的角色。它負責接收客戶端請求&#xff0c;并根據預定義的規則將請求路由到對應的后端服務。Spring Cloud Gateway 是 Spring 官方推出的一款高性能網關&#xff0c;支持動態路由、…

打造高功率、高電流和高可靠性電路板的厚銅PCB生產

厚銅PCB生產是指制作一種具有較厚銅層的PCB&#xff08;Printed Circuit Board&#xff0c;印刷電路板&#xff09;。這種PCB通常用于高功率、高電流和高可靠性的電子設備中。厚銅PCB的生產過程包括以下幾個 主要步驟&#xff1a; 1. 基材準備 厚銅PCB的基材通常采用FR4或CEM-…

軟考高級-系統架構設計師 論文范文參考(一)

文章目錄 論SOA技術的應用論SOA在企業信息化中的應用論UP&#xff08;統一過程方法&#xff09;的應用論分布式數據庫的設計與實現論改進Web服務器性能的有關技術論基于UML的需求分析論基于構件的軟件開發論基于構件的軟件開發(二) 論SOA技術的應用 摘要&#xff1a; ?本人于…

京東平臺關鍵字搜索接口開發指南:Python實現與代碼詳解

一、接口概述 京東關鍵字搜索接口允許開發者通過HTTP請求獲取平臺商品的關鍵字搜索結果&#xff0c;常用于商品比價、數據分析等場景。本文基于Python演示如何調用京東搜索接口&#xff0c;解析返回數據并實現基礎功能。 二、技術實現步驟 接口地址分析? 京東未完全公開API…

淺析鎖的應用與場景

鎖的應用與場景&#xff1a;從單機到分布式 摘要&#xff1a;在多線程和分布式系統中&#xff0c;“鎖”是避免資源競爭、保障數據一致性的核心機制。但你真的了解鎖嗎&#xff1f;什么時候該用鎖&#xff1f;用哪種鎖&#xff1f;本文通過通俗的比喻和代碼示例&#xff0c;帶…

30天通過軟考高項-第三天

30天通過軟考高項-第三天 任務&#xff1a;項目范圍管理 思維導圖閱讀 知識點集錦閱讀 知識點記憶 章節習題練習 知識點練習 手寫回憶ITTO 聽一遍喜馬拉雅關于范圍的內容 范圍管理-背 1. 過程定義 規劃變瘦訂份缺孔 規劃范圍管理&#xff1a;為了記錄如何定…

文字過長使用省略號展示,text-overflow 的使用和不生效場景的解決辦法,flex 布局中文字省略展示的坑

在前端開發過程中【單行文本內容過長使用省略號展示】這是一個特別常見的功能&#xff0c;大家都知道要使用 text-overflow 這個 css 屬性。 關于這個屬性&#xff0c;我們可以先看一下官方文檔怎么說。 text-overflow CSS 屬性用于確定如何提示用戶存在隱藏的溢出內容。其形式…

(二)讀寫分離架構、冷熱分離架構

文章目錄 讀寫分離架構什么是讀寫分離結構架構模型優缺點優點缺點 技術案例寫情況讀情況 冷熱分離架構什么是冷熱分離架構?架構模型優缺點優點 缺點技術案例讀數據寫數據 讀寫分離架構 什么是讀寫分離結構 讀寫分離架構針對于數據庫。數據庫原本負責讀寫兩個功能。 讀寫分離架…

windows中kafka4.0集群搭建

參考文獻 Apache Kafka windows啟動kafka4.0&#xff08;不再需要zookeeper&#xff09;_kafka壓縮包-CSDN博客 Kafka 4.0 KRaft集群部署_kafka4.0集群部署-CSDN博客 正文 注意jdk需要17版本以上的 修改D:\software\kafka_2.13-4.0.0\node1\config\server.properties配置文…

無線通信網

注意區分CA&#xff08;無線&#xff09;和CD&#xff08;有線&#xff09; 無線局域網擴頻技術 FHSS/DSSS 無線頻譜和信道&#xff1a;2.4G/5GHz,2.4GHz共13個信道&#xff0c;3個不重疊信道 CSMA/CA&#xff0c;隱藏節點 MANET 無線安全&#xff1a;WEP、WPA、WPA2、AES/TP…

嵌入式開發:基礎知識介紹

一、嵌入式系統 1、介紹 以提高對象體系智能性、控制力和人機交互能力為目的&#xff0c;通過相互作用和內在指標評價的&#xff0c;嵌入到對象體系中的專用計算機系統。 2、分類 按其形態的差異&#xff0c;一般可將嵌入式系統分為&#xff1a;芯片級&#xff08;MCU、SoC&am…

uv包管理器如何安裝依賴?

uv包管理器如何安裝依賴? 輸入 uv pip install 包名 uv pip install python-docx

大模型驅動智能服務變革:從全流程賦能到行業縱深落地

大模型技術的快速發展&#xff0c;正深刻改變著人工智能的研發與應用模式。作為"軟硬協同、開箱即用"的智能化基礎設施&#xff0c;大模型一體機通過整合計算硬件、部署平臺和預置模型&#xff0c;重構了傳統AI部署方式&#xff0c;成為推動AI普惠化和行業落地的重要…

【MQ篇】RabbitMQ之簡單模式!

目錄 引言一、 初識 RabbitMQ 與工作模式二、 簡單模式 (Simple Queue) 詳解&#xff1a;最直接的“點對點快遞” &#x1f4ee;三、 Java (Spring Boot) 代碼實戰&#xff1a;讓小兔子跑起來&#xff01; &#x1f430;&#x1f3c3;?♂?四、 深入理解&#xff1a;簡單模式的…

Lua 第7部分 輸入輸出

由于 Lua 語言強調可移植性和嵌入性 &#xff0c; 所以 Lua 語言本身并沒有提供太多與外部交互的機制 。 在真實的 Lua 程序中&#xff0c;從圖形、數據庫到網絡的訪問等大多數 I/O 操作&#xff0c;要么由宿主程序實現&#xff0c;要么通過不包括在發行版中的外部庫實現。 單就…