iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0

上一篇文章我們介紹了測試金字塔。今天我們就從金字塔的最下面開始,來分享如何在Angular專案中,導入Jest這個單元測試框架。


什麼是Jest

https://ithelp.ithome.com.tw/upload/images/20241010/20169487puVOGeR7Yy.png

Jest 是一個流行的行為驅動開發(BDD) JavaScript 測試框架,最初由 Facebook 開發。廣泛應用於 JavaScript 和 TypeScript 開發的應用。

Jest的特點在於,他提供了開箱即用的體驗,通常不需要繁瑣的配置。並且Jest 可以同時執行多個測試,這有助於加快測試速度,特別是在大型應用中。最後快照測試,模擬函式和模組,覆蓋率報告,等測試常用的功能也都有提供。

Jest的語法也非常簡單。

test('adds 1 + 2 to equal 3', () => {
  expect(1 + 2).toBe(3);
});

test代表一個獨立的測試案例,expect(1 + 2).toBe(3) 代表預期 1+2 的結果應該要是 3。

那為什麼要用Jest呢? Angular本身沒有搭配的測試框架嗎?


為什麼用Jest

其實Angular針對測試本身提供了 Angular Testing Utilities 搭配 JasmineKarma 作為測試的解決方案和環境。

Angular Testing Utilities,提供了一些內建的測試工具和服務,支援Angular應用與測試框架的交互,以便於撰寫和執行測試。

Jasmine 是一個行為驅動開發(BDD)的測試框架,而Karma則是一個測式執行器,能夠在瀏覽器中運行測試。

那麼為什麼不用原本提供的測試環境,而是要導入Jest呢?

首先,從Angular 16 開始,Karma 已經走入deprecated 並且 Jest 已經被加入Angular的實驗模式。所以可以理解成,Angular團隊正逐漸向Jest靠攏。除了這個原因外,實務層面包含幾個面向:

1. 簡化的配置和使用

  • 零配置:Jest 提供了一個開箱即用的體驗,通常不需要繁瑣的配置,而 Karma + Jasmine 通常需要更多的配置和設置工作。
  • 簡單的語法:Jest 的測試語法更加直觀,開發者可以更輕鬆地編寫測試用例。

2. 速度與性能

  • 並行測試:Jest 能夠並行運行測試,這樣可以顯著提高測試速度。Karma 每次都會啟動一個瀏覽器實例,這在大型應用中會導致測試變得緩慢。
  • 監聽文件變更:Jest 自帶的監聽功能可以在文件變更時自動運行相關測試,這使得開發過程更加高效,而 Karma 的監聽功能可能不如 Jest 方便。

3. 強大的模擬功能

  • 內建模擬:Jest 內建了模擬功能,使得開發者能夠輕鬆地模擬函式和模組,這對於測試依賴於外部資源的代碼非常方便。Karma 和 Jasmine 雖然也有模擬功能,但通常需要額外的配置和庫支持。

4. 快照測試

  • 快照測試:Jest 提供的快照測試功能可以輕鬆檢查 UI 元件的輸出,這對於測試應用的視覺一致性非常有用。Karma 和 Jasmine 雖然可以實現類似的功能,但需要更多的設置。

5. 代碼覆蓋率報告

  • 自動生成報告:Jest 能夠自動生成代碼覆蓋率報告,這使得開發者可以輕鬆了解測試的全面性。雖然 Karma 也可以生成覆蓋率報告,但設置和配置上通常更為複雜。

6. 社區支持和生態系統

  • 活躍的生態系統:Jest 擁有一個活躍的開發者社區,並且與其他現代工具(如 React、Vue)有著良好的整合,這使得使用 Jest 的開發者能夠受益於豐富的資源和支持。

7. 現代開發流程的適應性

  • 適合現代工具鏈:Jest 在許多現代 JavaScript 生態系統中被廣泛使用,與 Webpack、Babel 等工具的整合相對簡單,更適合現代前端開發的需求。

Angular應用導入Jest

準備好專案後第一步要做的就是移除Jasmine和Karma

1. 移除Jasmine和Karma

npm uninstall karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter @types/jasmine jasmine-core

2. 移除angular.json中的測試

"test": {
  "builder": "@angular-devkit/build-angular:karma",
  "options": {
    "polyfills": [
      "zone.js",
      "zone.js/testing"
    ],
    "tsConfig": "tsconfig.spec.json",
    "inlineStyleLanguage": "scss",
    "assets": [
      {
        "glob": "**/*",
        "input": "public"
      }
    ],
    "styles": [
      "src/styles.scss"
    ],
    "scripts": []
  }
}

3. 安裝 jest

npm i --save-dev jest @types/jest  jest-preset-angular

jest 測試框架。
@types/jest 是一個 TypeScript 的型別定義檔案包,提供了 Jest 框架的 TypeScript 支援。
jest-preset-angular 是一個專為 Angular 應用設計的 Jest 預設配置套件,提供了一些預設設置和工具,以便於在 Angular 環境中使用 Jest。

4. 在資料夾中建立 setup-jest.ts 檔案

加入檔案後,於其中import jest-preset-angular

import 'jest-preset-angular/setup-jest';

5. 使用 jest cli 指令建立 jest.config 檔案

npx jest — init

執行完後會新增一個 jest.config.js 或 .ts的設定檔。
將設定檔中的 setupFilesAfterEnv 調整為

setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],

假設我們使用的是 jest.config.ts 就需要安裝 ts-node。
ts-node 是一個 TypeScript 執行環境,允許我們直接運行 TypeScript 文件,而無需手動將它們編譯為 JavaScript。這樣,開發者可以更方便地測試和執行 TypeScript 代碼。

npm install ts-node --save-dev

6. 更新 tsconfig.spec.json 檔案

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "types": [
      "jest" // 1
    ],
    "esModuleInterop": true, // 2
    "emitDecoratorMetadata": true // 3
  },
  "include": [
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
  ]
}
  • extends:這個屬性表示當前配置文件繼承自其他配置文件(此例中是 ./tsconfig.json)。這意味著當前的配置會基於父配置進行擴展,並添加或覆蓋一些特定的選項。
  • outDir:
    • 設定編譯輸出的目錄,此例中指定為 ./out-tsc/spec。這意味著編譯後的 TypeScript 文件將被輸出到這個目錄中。
  • types:
    • 這個屬性告訴 TypeScript 編譯器要加載哪些型別定義。此例中,"jest" 表示要加載 Jest 的型別定義,以便在編寫測試時可以使用 Jest 提供的函式和匹配器,並獲得相應的型別檢查和自動補全支持。
  • esModuleInterop:
    • 這個選項允許在 TypeScript 中使用 ES 模組語法導入 CommonJS 模組。設置為 true 時,可以使用 import 語法導入 CommonJS 模組,這有助於提高與其他模組系統的兼容性。
  • emitDecoratorMetadata:
    • 這個選項啟用裝飾器元數據的生成。在使用 Angular 或類似框架時,這通常是必需的,因為許多框架依賴於裝飾器(例如,用於依賴注入)。設置為 true 會在編譯時生成額外的元數據,幫助這些框架正確運行。
  • include:
    • 這個屬性告訴 TypeScript 編譯器要包含哪些文件。在這個例子中,編譯器會包括所有在 src 目錄下,擁有 .spec.ts.d.ts 擴展名的文件。
    • .spec.ts 文件通常是測試文件,而 .d.ts 文件是型別定義文件。

7. 最後在 package.json 中加入執行 Jest測試的指令

"test-jest": "jest --verbose",
"test-jest:coverage": "jest --coverage",
"test-jest:watch": "jest --watch"

到這裡我們就成功在將Jasimine和Karma替換成Jest了! 下一篇文章我們會討論如何撰寫單元測試和測試切割的力度。

參考文獻:
Angular unit testing with Jest 2023 - by Megha D Parmar
Moving Angular CLI to Jest and Web Test Runner - by Doug Parker


上一篇
# 開心交付程式碼前,先補上測試 !
下一篇
# 使用Jest為Angular專案撰寫UnitTest(二)
系列文
轉生成前端工程師後,30步離開新手村!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言