(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取得部だけを直せば、ロジックのテストは修正不要か小さい修正で済みそうです。