透过 TDD 模式学习如何实现各种 npm 工具

前言

在程序員的日常精進之中,閱讀優秀的代碼是必不可少的。透過 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

使用搭建好的環境

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

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

使用方法

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

git clone https://github.com/calpa/tdd-playground.gitcd 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.me

上一篇:React性能优化 - react服务端同构SSR
下一篇::last-child的坑-CSS3选择器

相关推荐

  • 项目中npm依赖问题

    最近开发遇到一个npm依赖导致的问题,报错如下。 sloterror(https://img.javascriptcn.com/804ed4a03d02191762c1f48473ba1711 "sl...

    2 年前
  • 随记-npm

    npm npm是包管理器,方便开发人员分享,复用代码 用于搜索js模块/包的网站 npm服务器可下载或上传安装包或命令行程序 npm仓库存储安装包/安装模块 npm 安装 npm依赖于node,...

    4 个月前
  • 针对前端开发可重用组件并发布到NPM

    翻译:疯狂的技术宅 原文:https://www.smashingmagazine....(https://www.smashingmagazine.com/2018/07/reusablecom...

    1 年前
  • 通过npm引用的vue组件使用详解

    什么是组件:组件是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能。

    3 年前
  • 递归实现层级目录(React+AntdDesign)

    1.写在前面 作为前端小白的我一直对算法和数据结构浅尝辄止,哝,吃亏了。使用多次递归实现数据格式化后将数据进行树状展示的目的,分享一下我这次挠头的经历~ 2.数据 后台传过来的数据大概是这样的 ...

    1 个月前
  • 透过迷你vue库,了解vue背后思想

    更多详情请参考 http://www.zhangbing.name/Jav...(http://www.zhangbing.name/Javascript/%E9%80%8F%E8%BF%87%E8%...

    2 年前
  • 透过浏览器看HTTP缓存

    Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供IfModifiedSince头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。

    5 年前
  • 边学习变记:npm 常用的几个指令(持续更新。。。)

    在当前文件夹下,地址栏输入cmd 呼出控制台。1.npm init 初始化项目,npm init y 生成默认配置。 2.查看当前使用的镜像地址:npm get registry默认镜像地址:http...

    4 个月前
  • 踩坑札记之 npm 包发布

    重点阐述 npm 包发布前后所踩坑,首先科普如何发布 npm 包。 发布流程 注册账号 开启终端输入: 根据提示输入 username、password、email 即刻注册成功,已注...

    2 年前
  • 贡献你的力量 开发一个Vue组件并发布到npm

    最近在工作中写了一个面向 PC 端的 Vue 滚动组件,关于 PC 端的滚动组件以前也用过一些,但是没有找到特别满意的,所以自己想着把这个组件开源发布出去,希望能够帮到和我有类似需求的人吧! 目标 ...

    2 年前

官方社区

扫码加入 JavaScript 社区