Help us understand the problem. What is going on with this article?

素のECMAScriptだけで組める関数テスト

当記事では、素のECMAScriptだけで組める関数テスト用のES Modulesを書き残しています。

1. ソースコード

使い方は以下の通りです。

import {
  testFunction
} from "./original-test-tool.mjs";

// サンプル用の関数です。
const f = (a, b) => {
  return a + b;
};

// 試験を定義・実行します。
testFunction("f() の第1回試験", f, [1, 2], 3);
testFunction("f() の第2回試験", f, [3, 4], 7);
testFunction("f() の第3回試験", f, [1, 1], 999999);
testFunction("f() の第4回試験", f, [1, 1], "2");

実行するとコンソールにテスト結果が出力されます。

✔ f() の第1回試験

✔ f() の第2回試験

❌ f() の第3回試験
  想定: {Number} 999999
  実際: {Number} 2

❌ f() の第4回試験
  想定: {String} 2
  実際: {Number} 2

以下、全文です。

test.mjs
/**
 * 引数で受け取った値のデータ型を返す関数です。
 * @example
 *   // "Number"
 *   getType(1);
 * 
 *   // "String"
 *   getType("Hello world.");
 * 
 *   // "Array"
 *   getType([]);
 * @param {*} value 調べる対象となる値です。
 * @returns {String} データ型は文字列で返します。
 */
const getType = (value) => {
  return Object.prototype.toString.call(value).slice(8, -1);
};

/**
 * 関数をテストする関数です。
 * テスト結果に応じて、コンソールにメッセージを出力します。
 * @example
 *   const exampleFunction = (a, b) => {
 *     return a + b;
 *   };
 * 
 *   // ✔ exampleFunction() のテスト
 *   testFunction("exampleFunction() のテスト", exampleFunction, [1, 2], 3);
 * 
 *   // ❌ exampleFunction() のテスト
 *   // 想定: {Number} 5
 *   // 実際: {Number} 3
 *   testFunction("exampleFunction() のテスト", exampleFunction, [1, 2], 5);
 * @param {String} testName テスト名・テスト概要を表す文字列を指定してください。
 * @param {Function} testFunction テスト対象となる関数です。
 * @param {Array<*>} testArguments テスト対象となる関数に渡す引数です。
 * @param {*} correctTestReturnValue 想定される正しい戻り値です。undefinedは指定できません。 
 */
const testFunction = (testName, testFunction, testArguments, correctTestReturnValue) => {

  // 第1引数から第3引数までが正常であるか確認します。
  const parameterTypes = ["String", "Function", "Array"];
  const argumentTypes = [getType(testName), getType(testFunction), getType(testArguments)];
  for (let i = 0; i < argumentTypes.length; i += 1) {
    if (argumentTypes[i] !== parameterTypes[i]) {
      throw new TypeError(`${i + 1}引数には ${parameterTypes[i]} を指定してください。実際には ${argumentTypes[i]} が指定されています。`);
    }
  }

  // 第4引数が正常であるか確認します。
  if (getType(correctTestReturnValue) === "Undefined") {
    throw new TypeError("第4引数が指定されていないか、あるいはundefinedが指定されています。第4引数に、明示的にundefinedを指定することは許可されません。");
  }

  // 関数をテストし、その結果をコンソールに出力します。
  const testReturnValue = testFunction(...testArguments);
  if (testReturnValue === correctTestReturnValue) {
    console.log(`${testName}`);
  } else {
    console.log(`${testName}\n  想定: {${getType(correctTestReturnValue)}} ${correctTestReturnValue}\n  実際: {${getType(testReturnValue)}} ${testReturnValue}`);
  }
};

/**
 * ECMAScript環境だけで完全に動作するテスト用の関数・オブジェクトをまとめたモジュールです。
 * @author AGadget
 */
export {
  testFunction
}

2. おわりに

凄まじく単純なので実用性は無いでしょうが、これくらいのクオリティのものならば意外と作れるものですね。

AGadget
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away