純粋な関数は単体テストに最適です。特定の入力に対して、常に同じ出力が期待されます。内部状態は関係しません。いくつかの例と、メソッドが期待どおりに機能するかどうかを確認する簡単なテストを見てみましょう。
Jasmine は JavaScript の単体テスト フレームワークです。 Node.js またはブラウザーの両方でテストを実行できます。これは Angular フレームワークで使用されており、特に Angular ベースのプロジェクトで人気があります。これは、Vanilla JS プロジェクトや、他のフレームワークに基づくプロジェクトにも確実な選択肢です。
ハッピー パス テストとは、正常に動作すると予想される入力を使用してメソッドをテストすることです。引数は有効であり、妥当な範囲内です。これらのテストは、メソッドが正しく機能するかどうかをチェックします。テスト ケースは、ドキュメントでメソッドがどのように説明されているかを示す単純な例である必要があります。
疑似コードの例:
expect(add(2, 2)).toBe(4)
、
expect(concatenate(“Lorem”, “Ipsum”)).toBe(“LoremIpsum”)
これらのテストは、メソッド キーの動作が壊れるたびに自動的にそれを検出することを目的としています。
いくつかの簡単なメソッドを見てみましょう。実際のアプリケーションで必要になる可能性のある簡単な操作です。
すべての実装は大幅に簡素化されています。期待されるものとわずかに異なるパラメータを指定しただけでは、すべてのメソッドが醜い形で壊れてしまいます。コードは堅牢とは程遠いです。
ユーザーの名前と姓を挨拶するメソッド:
export function greet(name, surname) { return `Hello ${name} ${surname}!`; }
shortDate
は、日付オブジェクトを受け取り、それを短い文字列として書式設定して返す書式設定メソッドです。コード:
export function shortDate(date) { return date.toISOString().substring(0, 10); }
ellipsis
、長いテキスト文字列とオプションの長さパラメータを受け取り、制限内に収まるように文字列をトリミングします。
export function ellipsis(text, length = 50) { if (text.length > length) { return text.substring(0, length) + "…"; } return text; }
key
とlang
ペアの翻訳された文字列値を提供するメソッド。これは、より高度な翻訳ライブラリに置き換えることができるものの簡素化された実装です。
export function translate(key, lang = "en") { switch (lang) { case "en": switch (key) { case "hello": return "Hello!"; } case "pl": switch (key) { case "hello": return "Cześć!"; } } }
価格にパーセント割引を適用する方法。この単純な実装ではやりすぎのように感じるかもしれませんが、後でエッジケースを調査し始めると、はるかに興味深いものになるでしょう。
export function applyDiscount(price, discountPercentage) { return price - (price * discountPercentage) / 100; }
これは、指定された価格で複数のユニットを購入した場合の合計価格を計算します。また、興味深いエッジケースを追加すると、さらに複雑になります。
export function calculatePrice(unitPrice, quantity) { return unitPrice * quantity; }
完全な JS コード、 src/main.js
:
export function greet(name, surname) { return `Hello ${name} ${surname}!`; } export function shortDate(date) { return date.toISOString().substring(0, 10); } export function ellipsis(text, length = 50) { if (text.length > length) { return text.substring(0, length) + "…"; } return text; } export function translate(key, lang = "en") { switch (lang) { case "en": switch (key) { case "hello": return "Hello!"; } case "pl": switch (key) { case "hello": return "Cześć!"; } } } export function applyDiscount(price, discountPercentage) { return price - (price * discountPercentage) / 100; } export function calculatePrice(unitPrice, quantity) { return unitPrice * quantity; }
Jasmine を追加するには、まずフォルダーを npm パッケージに変換します。
$ npm init -y Wrote to …/package.json: …
次に、Jasmine パッケージをインストールします。
$ npm install --save-dev jasmine added 42 packages, and audited 43 packages in 2s 13 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
次に、Jasmine が使用するフォルダーとファイルを生成できます。
$ npx jasmine init (no output)
このコマンドにより次のものが生成されます。
spec/
— テストを含む*.spec.js
ファイルを配置できるフォルダー。
spec/support/jasmine.json
— Jasmine 構成を含むファイル。次の単体テストでは、ハッピー パスのみに焦点を当て、妥当な入力に対して結果が期待どおりであるかどうかを確認します。テストは一目瞭然なので、見てみましょう。
import { greet, shortDate, ellipsis, translate, applyDiscount, calculatePrice, } from "../src/main.js"; describe("main", () => { describe("greet", () => { it("should greet by name and surname", () => { expect(greet("Lorem", "Ipsum")).toEqual("Hello Lorem Ipsum!"); }); }); describe("shortDate", () => { it("should format correclty date", () => { const date = new Date("2023-11-02"); expect(shortDate(date)).toEqual("2023-11-02"); }); }); describe("shortDate", () => { it("should shorten long text at 50 chars", () => { expect( ellipsis( "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque a faucibus massa." ) ).toEqual("Lorem ipsum dolor sit amet, consectetur adipiscing…"); }); it("should leave short text unchanged", () => { expect(ellipsis("Lorem ipsum sin dolor")).toEqual( "Lorem ipsum sin dolor" ); }); it("should shorten to custom length", () => { expect(ellipsis("Lorem ipsum sin dolor", 10)).toEqual("Lorem ipsu…"); }); }); describe("translate", () => { it("should translate to supported langauges", () => { expect(translate("hello", "en")).toEqual("Hello!"); expect(translate("hello", "pl")).toEqual("Cześć!"); }); }); describe("applyDiscount", () => { it("should lower the price accordingly", () => { expect(applyDiscount(120, 25)).toEqual(90); expect(applyDiscount(8, 50)).toEqual(4); }); }); describe("calculatePrice", () => { it("should find a price of many products", () => { expect(calculatePrice(4, 3)).toEqual(12); expect(calculatePrice(9, 0.5)).toEqual(4.5); }); }); });
(ファイルspec/main.spec.js
)
テストを実行するには、次のスクリプトをpackage.json
に追加します。
.. "scripts": { "test": "jasmine" }, …
これを配置すると、 npm run test
でテストが実行されます。
$ npm run test > [email protected] test > jasmine Randomized with seed 76873 Started ........ 8 specs, 0 failures Finished in 0.004 seconds Randomized with seed 76873 (jasmine --random=true --seed=76873)
この投稿では、JS コードの簡単な例と、それを単体テストでどのようにカバーできるかを見ていきました。完全なコード例は GitHub にあります。
ここでも公開されています