やるべきことが少なすぎると、時々おかしなアイデアが生まれることがあります。 v8 エンジンを埋め込むことで、完全な DOM 実装と JavaScript サポートを備えたヘッドレス ブラウザを Go で作成することでした。
すべては HTMX アプリケーションを作成することから始まり、それをテストする必要があったため、ヘッドレス ブラウザの純粋な Go 実装があるかどうか興味を持ちました。
「ヘッドレス ブラウザに行く」を検索すると、ヘッドレス ブラウザの自動化、つまりヘッドレス モードで Firefox や Chrome などの実際のブラウザを使用することについてのみ検索結果が表示されました。
しかし、純粋な Go には何もありません。
それで私はそれを作り始めました。
ヘッドレス ブラウザを作成しても、実際のブラウザのようには動作しないため、ばかげているように思えるかもしれません。そのため、サポートすることを決定したすべてのブラウザーでアプリケーションが正しく動作するかどうかを実際に検証することはできません。また、動作が停止したときにアプリケーションのスクリーンショットなどの便利な機能を取得することもできません。
それではなぜでしょうか?
効果的な TDD ループで動作するには、テストが高速である必要があります。テストの実行が遅いと TDD が妨げられ、高速フィードバック ループによってもたらされる効率性のメリットが失われます。
この種の検証にブラウザ自動化を使用すると、重大なオーバーヘッドが発生し、通常、このようなテストはコードが記述された後に記述されます。そのため、それらは正しい実装を作成する助けにはなりません。しかし、事後のメンテナンスの負担は軽減されます。お金を払っている顧客より先にバグを検出するのは、ごく稀です。
目標は、TDD プロセスをサポートするツールを作成することです。使用するには、インプロセスで実行する必要があります。
Go で記述する必要があります。
DOM をインプロセスにすると、DOM 上に優れたラッパーを作成できるようになります。これは、JavaScript の testing-library と同様に、テストに不安定性の少ないインターフェイスを提供するのに役立ちます。
CSS クラス名、要素 ID、または DOM 構造に依存するのではなく、次のようにユーザー中心の言語でテストを作成します。
「メール」というラベルが付いたテキストボックスに「me@example.com」と入力します
または仮説のコード内。
testing.GetElement(Query{ role: "textbox", // The accessibility "name" of a textbox _is_ the label name: "Email", }).type("me@example.com")
このテストでは、ラベルが
これにより、動作の検証が UI の変更から切り離されます。ただし、テキスト「電子メール」がアクセス可能な方法で入力フィールドに関連付けられることを強制します。これにより、テストがユーザーがページとどのように対話するかに結合されます。ページの使用にスクリーン リーダーに依存しているも含まれます。
これにより、TDD の最も重要な側面が達成されます。具体的な動作に関連付けられたテストを作成します。1
アウトプロセス ブラウザーに対して同じテストを作成することはおそらく技術的には可能ですが、ネイティブ コードの利点は、これらの種類のヘルパーに必要となる可能性が最も高い DOM のランダム アクセスの種類に不可欠です。
テストの種類を例示するために、JavaScript の同様の例を使用します。 HTMX を使用するアプリケーションでもあります。このテストでは、認証が必要なページのリクエストから一般的なログイン フローを検証します。
ここではすべてのセットアップ コードとヘルパー コードを 1 つのテスト関数にまとめているため、少し長くなります。
testing.GetElement(Query{ role: "textbox", // The accessibility "name" of a textbox _is_ the label name: "Email", }).type("me@example.com")
簡単に言えば、テストは次のことを行います:
テストは内部的に HTTP サーバーを起動します。これはテスト プロセスで実行されるため、ビジネス ロジックのモック化およびスタブ化が可能です。テストでは、jsdom を使用して HTTP サーバーと通信します。これは、HTML 応答を DOM に解析するだけでなく、初期化されたサンドボックスでクライアント側のスクリプトも実行します。 window をグローバル スコープとして使用します。3
これにより、応答の内容を検証するだけでは不十分な HTTP 層のテストを作成できるようになります。この場合;応答が意図したとおりに HTMX によって処理されていること。
しかし、テストが早く (または遅すぎ) ないようにいくつかの HTMX イベントを待つことを除けば、テストは実際には HTMX を考慮しません。実際、従来のリダイレクトを使用してフォームから HTMX を削除しても、テストは合格します。
(HTMX