「テストしやすいレガシーJS」の設計図 – DOM操作とロジックを分離する

(Reactではなく)DOMを操作するJSを想定

「入力、データ加工、出力」を分離して実装すると、
・AIがテストを実装しやすく
・人間がレビューしやすいテストを作ってくれます

document.querySelector("#submit").addEventListener("click", (event) => {
  const beforeData =  DOMからDTOを作成する(); // 入力
  const afterData = データ加工(beforeData);  // 加工 (Pure   Logic)
  DTOをDOMに反映する(afterData); // 出力
});Code language: JavaScript (javascript)

「DOMからDTOを作成する」のテスト

DOM -> DTO (入力): HTMLの構造に依存する部分です。

document.body.innerHTML = `<div>xxx</div>`; にデータを用意して、関数を呼び、期待するDTOが返ってくるかをテストします。

正常系は、1パターン。
異常系は、セレクタがない、データがない、データの形式が違う、などの数パターンをテストします。

「データ加工」は純粋なロジックとして分離:DOM不要で爆速テスト

DTO -> DTO (加工): 純粋なJSロジック。

入力(DTO)に対して必ず同じ出力(DTO)を返す「純粋な関数(Pure Function)」にすることで、jsdom の重いセットアップから解放されます。

データ駆動的なテストができます。
AIに依頼すれば、人間が作るテストよりも網羅的なテストを作ってくれます。

「DTOをDOMに反映する」のテストはDTOが正しい前提なので正常系のみでOK

document.body.innerHTML = `<div>xxx</div>`; にデータを用意して、関数にDTOを渡して、期待したDOMになるかをテストします。

DTOが担保されているので、正常系のみでOK

Event (結合): すべてをつないでAAAパターンで1件回す。

イベントを発火させて、DOMが期待どおりに変更されることをテストします。

正常系の1パターンでOK。

AIに依頼するときは、モックは必要最小限と指示するか、「DOMからDTOを作成する()、データ加工(beforeData)、DTOをDOMに反映する(afterData)は本物を呼んでください、モックにしないでください、ブラックボックステストとしてテストを作って」と指示します。

AAAパターン: Arrange(準備), Act(実行), Assert(検証)の略。テストコードの標準的な構成。

メリット

  • jsdomのセットアップが最小限で済みます
    • ロジック部分(データ加工)のテストにはDOMが不要なので、テストが高速に動きます。
  • 人間がレビューしやすい
    • 「入力、データ加工、出力」が分離されていない状態で、Event(結合)テストをAIに書かせると、時間がかかったり、無限ループに入ることがあります。書いてくれたとしても、モックを使いまくった長いテストで、人間がレビューするのは難しいテストコードができあがってきます。
    • 分割せずにAIに依頼すると、AIは複雑さを解決するために『とりあえずモックで固める』という逃げ道を使いがちです。構造を分けることで、AIに『逃げ道』を与えず、シンプルで堅牢なテストを書かせることができます。
  • サーバー側のHTMLレンダリング変更に強い
    • DOM取得部だけを直せば、ロジックのテストは修正不要か小さい修正で済みそうです。
タイトルとURLをコピーしました