iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 10
1
Software Development

為什麼世界需要Typescript系列 第 10

開始建立測試 - 10

tsconfig.json 簡介

tsconfig.json 是TypeScript 編譯專案時的編譯設定檔案, 能讓你指定編譯的TypeScript 原始碼檔案位置, 設定輸出目錄等.

一般情況下, 專案目錄大致都會這樣安排

├── dist
├── node_modules
├── src
| └── Observer.ts
├── package.json
└── tsconfig.json

以下是tsconfig.json 的示範設定

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "outDir": "./dist",
    "sourceMap": true
  },
  "files": [
    "boot.ts",
    "app.ts",
    "company.ts"
  ]
}

首先介紹tsconfig.json 編譯組態的一些常用設定.

key 說明
baseUrl 原始碼模組間關係時的根目錄
outDir 編譯後的結果要輸出到哪裡
sourceMap 是否需要啟動?
target 輸出 ECMAScript 版本, 預設是 ES5, 有ES3, ES5, ES6/ES2015, ES2016, ES2017, ESNext
removeComments 是否要移除註解
noImplicitAny 是否不允許將沒有設定類型的變數設定為 any
module 打包後的模組載入方式, 可供設定有None, CommonJS, AMD, System, UMD, ES6, ES2015, ESNext
lib 需包含至編譯過程中的 Library 檔案
paths 設定 import 的路徑別名對應表
exclude 排除資料夾或檔案

files

若不指定 files 屬性, TypeScript 預設會編譯根目錄以及子目錄下的 .ts 檔案, 但若特別指定 files, 則只會編譯有指定的 .ts 檔案.

通常 tsconfig.json 最常用的設定是 include . 一個典型的例子如下

{
   "compilerOptions": {
      "baseUrl": "./src",
      "outDir": "./dist",
      "lib": ["es2015", "dom", "esnext"]
   },
   "include": [
      "src/**/*"
   ],
   "exclude": [
      "node_modules",
      "**/*.spec.ts"
   ]
}

這樣開發專案過程當中, 新增移除原始碼檔案的時候, 就不用手動加 .ts 檔案在 tsconfig.json 內.

files 內容指定包含相對路徑或是絕對路徑的 ts 檔案清單, 不能用匹配表(regex)

include 內容指定一個文件的匹配表達路徑, 如 src/*/.ts 尋找 src 底下所有的 ts 檔案.

良好的開發習慣

工欲善其事, 必先利其器, 先別急著一頭熱就栽進開發的坑裡, 在這之前應該先知道測試的基本概念與正確作法, 開發專案的過程當中, 我們免不了多少要進行一些測試, 測試大致分為三種

  • 單元測試 (Unit testing)
  • 整合測試 (Integration testing)
  • 端對端測試 (End-to-end testing)
測試種類 說明
單元測試 是程式碼的最小單位進行測試, 所以這種測試類型通常執行速度快(測試範圍小).
整合測試 跨越單元測試的範圍, 對不同模組之間的交互作用進行測試
端對端測試 是從使用者的角度出發對真實的系統進行測試, 你所要準備的測試環境就是一套完整的系統

很多老闆喜歡"端對端測試", 因為它以真實的系統進行測試, 從開啟瀏覽器開始, 一步步的操作與輸入進行互動, 然後直接透過畫面顯示狀態來判斷其結果是否符合預期. 這卻導致大部分老闆花費很多人力投入端對端測試, 不願意花費人力進行單元測試, 整合測試. 這就是坊間流行的"測試冰淇淋".

分層自動化測試那個經典的"金字塔"說明了大部分的端對端測試都是很高成本.

UI自動化測試一直都是如此的令人糾結, 我始終認為金字塔高層測試只是測試防護體系的第二防線. 如果高層測試失敗了, 不僅僅表明功能程式碼中存在bug, 當bug 發生的時候, 開發人員還是得馬上火速處理, 一層一層找出問題在哪裡, 尋找bug 的過程是很漫長的, 就算找到bug 之後, 修改完的程式碼更新, 也不能保證不會再一次產生其他問題, 然後等到發佈到真實系統, 才能檢查發現是否有其他問題存在.

撰寫單元測試/整合測試程式的價值在於

當異動程式碼的時候, 不必等到發佈到真實系統, 假如發生bug 的時候可以立即馬上知道. 而且重點是可以馬上知道bug 發生的地方在哪裡, 不必花大量的時間去追蹤bug 在哪裡.

人非聖賢, 孰能無過, 人工手動測試總有疏漏之處, 就算你有完整的測試項目清單, 畢竟重複的工作做久了都會厭煩, 打從心裡認為不會出錯的功能, 自然也會測試的比較隨便些, 這是人之常情.

所以你在開始撰寫端對端測試之前, 應該要先想想QBQ (問題背後的問題)

QBQ 源自John G. Miller 出的一本書, 叫The Question Behind The Question 問題背後的問題

要不要"端對端測試" 只是 "冰山的一角", 冰山的主體(問題的根源) 應該是找出這個功能問題的背後的原因, 是不是能夠用單元測試/整合測試能夠找到問題?

例如

打開網站首頁, 結果網頁一片空白.

這問題發生的背後原因有很多種....

難道我們就得花很大精力和時間寫好一個端對端測試, 然後又花了漫長啟動端對端測試時間, 結果測出來就是 "網頁一片空白", 不通過! 哈!? 就這樣?!

開發人員看到這測試失敗結果, 但是仍然不知道出錯在哪裡? 只能另外再花大量時間去翻出程式碼和Log 歷史紀錄, 去追蹤Bug 在哪裡?

你可以想像在你的開發一天整天當中, 大部分時間都要花費在Debug 上面, 這聽來多駭人聽聞! 路怎麼走? 你自己決定!

單元測試

現在回到單元測試, TDD 是一種開發方法, 不是測試(雖然說它跟單元測試有關聯). TDD 的全名是Test Driven Development.

TDD 的三大法則:

  • 在撰寫一個單元測試前, 不可撰寫任何產品程式.
  • 只撰寫剛好無法通過的單元測試, 不能編譯也算無法通過.
  • 只撰寫剛好能通過當前測試失敗的產品程式.

它是一種程式開發的技巧, 簡單來說就是先寫測試程式, 然後才實作功能.


上一篇
觀察者模式 - 09
下一篇
簡單的Git 操作 - 11
系列文
為什麼世界需要Typescript30

1 則留言

0
andy840119
iT邦新手 5 級 ‧ 2020-05-15 17:38:30

TDD真的很好用
尤其是拿來寫Library
當你的Library寫完後
Test case剛剛好都出來了

我要留言

立即登入留言