透過 TDD 模式學習如何實現各種 npm 工具

作者: Calpa Liu
字數:960
出版:2018 年 11 月 2 日
#Readings#JavaScript
在程序員的日常精進之中,閱讀優秀的代碼是必不可少的。透過 TDD 的開發模式,可以模仿那些優秀的代碼,從而提升自己代碼水平。下面介紹如何從零開始搭建 TDD 環境,並構建 isEven 代碼

Test Driven Development (TDD),指的是先寫最小部分的測試代碼,然後寫開發業務代碼,通過測試。然後重構,並不更改測試用例的表現方式。

好處

  1. 節省重複手動測試代碼是否正常的時間
  2. 輕鬆寫測試代碼
  3. 通過測試用例就可以輕鬆喝茶

已實現工具

在過去的一段時間里,我閱讀了一些下載量大,並以 TDD 開發模式實現的一些工具庫。比如說:

  1. isEven
  2. isObject
  3. isNumber
  4. isEmptyObject
  5. extend
  6. underscore/keys

如何開始?

學習 TDD,我們首先需要搭建一個可以提供單元測試環境,比如利用 ava 測試工具。

搭建單元測試環境 SOP

  1. 構建新項目:mkdir tdd-playround
  2. 進入項目:cd tdd-playgound
  3. 在項目裡面構建 srctest 文件夾:mkdir srcmkdir test
  4. npm init -y 來構建 npm 包
  5. 運行命令 npx create-ava --next
  6. 然後運行 npm-scripts:npm run test -- --watch

Imgur
Imgur

使用搭建好的環境

與其搭建一個 TDD 環境,不如用已經搭建好的環境。

tdd-playground 自帶測試代碼以及環境。

使用方法

只需要 Clone 下來,然后安裝就行了。

```
git clone https://github.com/calpa/tdd-playground.git
cd tdd-playground
npm install
npm run test
```

如何使用這個工程?

  1. 你可以移走整個 src 文件夾,然後重新編寫你的 js 文件。

  2. 你可以移走部分的src/*.js 文件,然後重新編寫該部分文件。

    git mv ./src ./answer
    npm run test

值得注意的是,使用 git mv 而不是 mv 命令的話,可以避免 git log 混亂的問題。

TDD 的 SOP

這裡介紹一個最簡單的工具:isEven(測試是否雙數)

這裡 isEven 可以取代為任意有效 JS 名稱:

  1. 首先執行 npm run test -- --watch 自動監控代碼變化

  2. 構建測試代碼,以 isEven.test.js為 Javascript 測試代碼的名稱

  3. test/isEven.test.js 寫下以下代碼:

    import test from 'ava';
    const isEven = require('../src/isEven');
    
    test("isEven should be a function", t => {
        t.deepEqual(typeof isEven, "function", "isEven is not a function");
    });
  4. 測試代碼此時有報錯信息,原因是我們現在沒有寫/src/isEven.js

  5. /src/isEven.js裡面寫下基本函數:

    const isEven = () => {
    
    };
    
    module.exports = isEven;

    值得注意的是,由於我們在低版本的 Node.js 環境下,無法使用 import/export 語法。

  6. (再次運行 npm run test),這個時候你就可以看到已經通過測試了。

isEven 代碼解讀

  1. 我們要引入測試工具,以及代碼片段:

    const test = require("ava");
    const isEven = require("../src/isEven");
  2. 我們要寫一個確認該函數是否存在的測試用例:

    test("isEven should be a function", t => {
     t.deepEqual(typeof isEven, "function", "isEven is not a function");
    });
  3. 先寫一些正常的測試用例:

    test("should be true", t => {
      t.true(isEven(2));
      t.true(isEven(42));
      t.true(isEven(999994));
      t.true(isEven(-2));
      t.true(isEven(-10));
    });
  4. 此時,/src/isEven.js 應該有正常的代碼:

    const isEven = item => {
    return !(item % 2);
    };

    結果是返回 x mod 2 === 0,很簡單。

  5. 然後,再測試單數。

    test("should be false", t => {
      t.false(isEven(3));
      t.false(isEven(9));
      t.false(isEven(3));
      t.false(isEven(-9));
    });
  6. 再加極端值:

    test("should not take infinite number", t => {
      t.deepEqual(isEven(Infinity), "expect finite number");
    });
    
    test("should not take non integer", t => {
      t.deepEqual(isEven(0.1234), "expect integer");
    });
    
    test("should not take unsafe integer", t => {
      t.deepEqual(isEven(Math.pow(2, 53)), "expect safe integer");
    });
  7. 再運行 npm run test。 這個時候,我們就跑不過測試用例了。

  8. 我們要把 isEven 改成只讀安全的整數:

    const isEven = item => {
     if (!Number.isFinite(item)) {
       return "expect finite number";
     }
    
     if (!Number.isInteger(item)) {
       return "expect integer";
     }
    
     if (!Number.isSafeInteger(item)) {
       return "expect safe integer";
     }
    
     return !(item % 2);
    };
  9. 再次運行 npm run test 這個時候,就可以綠燈全開。

  10. 然後,你就可以愉快地重構,實現方式可以不同,但必須通過測試用例。

TODO

  1. isURL
  2. 判斷各種 JavaScript 基本類型的工具
  3. underscore
  4. moment/dayjs
  5. isPromise

後記

如果你有興趣學習 TDD 的話,你可以到我的 tdd-playground 下 fork + star。

關於 Calpa

Calpa 擅長使用 TypeScriptReact.jsVue.js 建立 Responsive Website。

他積極參與開源社區,曾在 2019 年的香港開源大會上擔任講者,提供工作經驗和見解。此外,他也在 GitHub 上公開分享個人博客程式碼,已獲得超過 300 顆星星和 60 個分支的支持。

他熱愛學習新技術,並樂意分享經驗。他相信,唯有不斷學習才能跟上快速演變的技術環境。

熱門文章

最新文章

圖片管理中心
管理圖片資源
IP 查詢
快速查詢和定位 IP 地址的地理位置和相關信息
Python 運行器
無需後端、無需登入,只需打開瀏覽器即可運行 Python 代碼(由 Pyodide 提供支持)
封面圖生成器
自動創建適合各種平台的文章封面圖
原作(青山剛昌)產生器
一鍵創建原作(青山剛昌)的封面圖
日本色彩
探索和使用傳統日本色彩
部落格內容洞察儀表板
以視覺化儀表板方式追蹤文章成效、分享熱度與分類分布,協助創作者掌握內容表現。
蒙特卡羅估算 π
使用蒙特卡羅方法演示 π 值的估算過程
LLM
使用 LLM 模型進行聊天
活動圖生成器
一鍵創建活動的封面圖
Wagmi Card
一鍵創建 Wagmi 的封面圖
Facebook Quote
Facebook Quote
Music Macro Language (MML) Studio
用程式語法編寫旋律,用音符構築想像
Blurhash
一鍵創建 Blurhash
文字分類器
使用 MediaPipe TextClassifier 分類文字
前端工程師免費工具資源
前端工程師免費工具資源
後端工程師免費工具資源
後端工程師免費工具資源
全端工程師免費工具資源
全端工程師免費工具資源
Web3 工程師免費工具資源
Web3 工程師免費工具資源
紫微斗數排盤系統|結合 AI 的命盤性格與事業財務分析生成器
紫微斗數排盤工具,輸入生日與時辰,自動生成完整命盤分析提示(Prompt)。結合最專業紫微理論與 AI 助力,助你深入解析性格、事業、財務與人際課題。免費使用,適合命理師及紫微愛好者。
PixAI Prompt 組合器|快速打造可用於 AI 繪圖的語言拼圖
使用 PixAI 卻不會寫 prompt?這個工具幫你一鍵組裝角色、表情、風格語彙,輸出高品質繪圖提示語句(Prompt),可直接貼入 PixAI 使用。適合插畫師、創作者、AI 新手與 VTuber 角色開發者。