給急躁的程式設計師的 JavaScript(ES2022 版)
請支持這本書:購買捐款
(廣告,請不要封鎖。)

10 測驗和練習入門



在大部分章節中,都有測驗和練習。這些都是付費功能,但提供全面的預覽。本章說明如何開始使用它們。

10.1 測驗

安裝

執行測驗應用程式

10.2 練習

10.2.1 安裝練習

安裝練習

10.2.2 執行練習

10.3 JavaScript 中的單元測試

本書中的所有練習都是透過測試架構 Mocha 執行的測試。本節將簡要介紹。

10.3.1 典型的測試

典型的測試程式碼分為兩部分

例如,以下兩個檔案

10.3.1.1 第 1 部分:程式碼

程式碼本身位於 id.mjs

export function id(x) {
  return x;
}

這裡的重點是:我們要測試的所有內容都必須匯出。否則,測試程式碼無法存取它。

10.3.1.2 第 2 部分:測試

  別擔心測試的具體細節

您不必擔心測試的具體細節:它們總是為您實作。因此,您只需要閱讀它們,但不需要撰寫它們。

程式碼的測試位於 id_test.mjs

// npm t demos/quizzes-exercises/id_test.mjs
suite('id_test.mjs');

import * as assert from 'assert/strict'; // (A)
import {id} from './id.mjs'; // (B)

test('My test', () => { // (C)
  assert.equal(id('abc'), 'abc'); // (D)
});

此測試檔案的核心在於 D 行,即 斷言assert.equal() 指定 id('abc') 的預期結果為 'abc'

至於其他行

若要執行測試,我們在命令列中執行下列指令

npm t demos/quizzes-exercises/id_test.mjs

ttest 的簡寫。亦即,此指令的長版本為

npm test demos/quizzes-exercises/id_test.mjs

  練習:你的第一個練習

下列練習讓你初步了解練習的樣貌

10.3.2 Mocha 中的非同步測試

  閱讀

你可能想要等到讀到非同步程式設計的章節時再閱讀本節。

為非同步程式碼撰寫測試需要額外的作業:測試會稍後收到結果,且必須在傳回時向 Mocha 示意它尚未完成。下列小節會探討三種這樣做的方式。

10.3.2.1 透過回呼的非同步性

如果我們傳遞給 test() 的回呼有參數(例如 done),Mocha 會切換到基於回呼的非同步性。當我們完成非同步作業時,必須呼叫 done

test('divideCallback', (done) => {
  divideCallback(8, 4, (error, result) => {
    if (error) {
      done(error);
    } else {
      assert.strictEqual(result, 2);
      done();
    }
  });
});

以下是 divideCallback() 的樣貌

function divideCallback(x, y, callback) {
  if (y === 0) {
    callback(new Error('Division by zero'));
  } else {
    callback(null, x / y);
  }
}
10.3.2.2 透過 Promise 的非同步性

如果測試傳回 Promise,Mocha 會切換到基於 Promise 的非同步性。如果 Promise 已完成,則測試會被視為成功;如果 Promise 被拒絕或完成花費的時間超過逾時,則測試會失敗。

test('dividePromise 1', () => {
  return dividePromise(8, 4)
  .then(result => {
    assert.strictEqual(result, 2);
  });
});

dividePromise() 的實作如下

function dividePromise(x, y) {
  return new Promise((resolve, reject) => {
    if (y === 0) {
      reject(new Error('Division by zero'));
    } else {
      resolve(x / y);
    }
  });
}
10.3.2.3 非同步函式作為測試「主體」

非同步函式總是傳回 Promise。因此,非同步函式是實作非同步測試的便利方式。下列程式碼等同於前一個範例。

test('dividePromise 2', async () => {
  const result = await dividePromise(8, 4);
  assert.strictEqual(result, 2);
  // No explicit return necessary!
});

我們不需要明確傳回任何內容:隱含傳回的 undefined 用於完成此非同步函式傳回的 Promise。如果測試程式碼擲回例外,非同步函式會負責拒絕傳回的 Promise。