GalenFrameworkを使用したレイアウトテストの技術

公開: 2022-03-10
簡単な要約↬グラフィカルユーザーインターフェイスを設計する場合、常に未解決の質問があります。それをテストするためにどのように自動化するのでしょうか。 また、Webサイトのレイアウトが応答性を維持し、さまざまな解像度のすべての種類のデバイスで正しく表示されるようにするにはどうすればよいでしょうか。 これに加えて、動的コンテンツ、国際化とローカリゼーションの要件から生じる複雑さは、実際の課題になります。 この記事では、興味深い新しいレイアウトテスト手法について説明します。 Galen Frameworkを使用して、意味のある一般化されたレイアウトテストを作成するための詳細なチュートリアルを提供します。このチュートリアルは、任意のブラウザーとデバイスで実行でき、同時に設計ドキュメントの信頼できる唯一の情報源として使用できます。

グラフィカルユーザーインターフェイスを設計するときは、常に未解決の質問があります。それをテストする方法を自動化するにはどうすればよいでしょうか。 また、Webサイトのレイアウトが応答性を維持し、さまざまな解像度のすべての種類のデバイスで正しく表示されるようにするにはどうすればよいでしょうか。 これに加えて、動的コンテンツ、国際化とローカリゼーションの要件から生じる複雑さは、実際の課題になります。

この記事では、興味深い新しいレイアウトテスト手法について説明します。 Galen Frameworkを使用して、意味のある一般化されたレイアウトテストを作成するための詳細なチュートリアルを提供します。このチュートリアルは、任意のブラウザーとデバイスで実行でき、同時に設計ドキュメントの信頼できる唯一の情報源として使用できます。

SmashingMagの詳細

  • レスポンシブインターフェイス設計のためのビジュアルテスト駆動開発
  • アプリ、ゲーム、モバイルWebのテスト自動化の基本
  • 多様なテスト-ReactNativeアプリの自動化フレームワーク

また、案内広告WebサイトMarktplaatsのメッセージングページの最適化されたテストをどのように考案したかについても説明します。 ガレンの構文を独自の言語で拡張する方法、テストコードを改善する方法、レイアウトテストルーチンをアートに変える方法を学びます。

ジャンプした後もっと! 以下を読み続けてください↓

ガレンフレームワークの紹介

Galen Frameworkは、1年前に「レスポンシブインターフェイス設計のためのビジュアルテスト駆動開発」で取り上げられました。 当時、その構文は制限されていました。 それ以来、大幅に改善され、多くの新機能が追加されました。これについては、ここで説明します。

Galen Frameworkに慣れていない場合は、Galen Specsという名前の独自のテスト言語を使用して、レスポンシブでクロスブラウザのレイアウトテストと機能テストを行うためのツールです。 これはSeleniumWebDriverに基づいており、WebDriverを直接操作できる豊富なJavaScriptAPIも備えています。 WebDriverを制御できるため、任意のブラウザー、クラウド(SauceLabs、BrowserStack、PerfectoMobileなど)、またはAppiumを使用する実際のモバイルデバイスでテストを実行できます。

インストールと実行

GalenFrameworkの設定は簡単です。 次のコマンドを実行するだけで、npmを介してインストールできます。

 npm install -g galenframework-cli

npmを使用しない場合は、最新のGalen Frameworkアーカイブをダウンロードし、パッケージを抽出して、インストール手順に従ってください。

インストールすると、GalenFrameworkはさまざまな方法で起動できます。 たとえば、 checkコマンドを使用して、単一ページのクイックテストを起動できます。 このコマンドでは、レイアウト検証を含む.gspecファイルを提供する必要があります。その後、次のように呼び出すことができます。

 galen check loginPage.gspec --url https://example.com --size 1024x768 --include desktop --htmlreport reports

このコマンドは、ブラウザを起動し、指定されたURLを開き、ブラウザウィンドウのサイズを1024×768ピクセルに変更し、 loginPage.gspecファイルで宣言されたすべての検証を実行します。 その結果、詳細なHTMLレポートが得られます。

テストスイートの管理

現実の世界では、実際のWebアプリケーションは純粋に静的なページで構成されているわけではありません。 確認したい場所にたどり着くには、多くの場合、いくつかのアクションを実行する必要があります。 この場合、Galenは、ページオブジェクトモデルを実装するためのJavaScriptテストスイートとGalenPages JavaScriptAPIを提供します。 JavaScriptGalenテストの簡単な例を次に示します。

 test("Home page", function() { var driver = createDriver("https://galenframework.com", "1024x768"); checkLayout(driver, "homePage.gspec", ["desktop"]); });

これは、実際のプロジェクトから取得した、ログインページのページオブジェクトモデルの実装です。

 WelcomePage = $page("Welcome page", { loginButton: "#welcome-page .button-login" }); LoginPage = $page("Login page", { username: "input[name='login.username']", password: "input[name='login.password']", loginButton: "button.button-login" loginAs: loggedFunction ("Log in as ${_1.username} with password ${_1.password}", function(user) { this.username.typeText(user.username); this.password.typeText(user.password); this.loginButton.click(); }) }); test("Login page", function() { var driver = createDriver("https://testapp.galenframework.com", "1024x768"); var welcomePage = new WelcomePage(driver).waitForIt(); welcomePage.loginButton.click(); new LoginPage(driver).waitForIt(); checkLayout(driver, "loginPage.gspec", ["desktop"]); });

高度な使用法については、GalenBootstrapプロジェクトを確認することをお勧めします。 これは、Galen専用に構築されたJavaScript拡張機能です。 UIテスト用の追加機能と、ブラウザーを構成して複雑なテストスイートを実行するためのより簡単な方法を提供します。

シンプルなレイアウトテスト

まず、GalenFrameworkで簡単なレイアウトテストを紹介します。 次に、高度なユースケースに進み、GalenSpecs構文を拡張する方法を示します。 このために、アイコンとキャプションが付いたヘッダーを確認します。

アイコンとキャプション
アイコンとキャプション(拡大版を表示)

HTMLコードでは、次のようになります。

 <body> <!-- … --> <div> <img class="header-logo" src="/imgs/header-logo.png"/> <h1>My Blog</h1> </div> <!-- … --> </body>

Galenレイアウトテストの最も単純な形式は、次のようになります。 まず、CSSセレクターでオブジェクトを宣言する必要があります。

 @objects header #header icon #header img caption #header h1

次に、意味のある名前でテストセクションを宣言し、その下にすべての検証を配置します。

 = Icon and Caption = icon: left-of caption 10 to 15px width 32px height 32px inside header 10px top caption: aligned horizontally all header inside header

ここでは、アイコンとキャプションの2つのヘッダー要素をテストしました。 アイコンとキャプション要素の下にリストされているすべての検証は、実際には標準のガレン仕様です。 これらの仕様は、独自のレイアウトテストソリューションを組み立てるための基本的な構成要素です。 各仕様は、単一のプロパティ(幅、高さ、テキストなど)、相対位置(内側、左、上など)、またはスクリーンショットのピクセル(配色、画像など)を検証します。

forEachループを使用した複数の要素のテスト

前の例は、単純なシナリオを示しています。 より複雑な状況、つまり水平メニューにどのように対処できるかを見てみましょう。 まず、簡単なレイアウトテスト手法を試してみましょう。

横メニュー
水平メニュー(拡大版を表示)

ページ上の複数の要素を照合することから始めます。 次のコードで、Galenに#menu ul liセレクターに一致する要素を検索するように指示しています。

 @objects menu #menu item-* ul li

後で、 menu.item-1menu.item-2のような名前でこれらのアイテムを参照し、 @forEachループを使用してすべてのメニューアイテムを反復処理できます。

 = Menu = menu.item-1: inside menu 0px top left bottom @forEach [menu.item-*] as menuItem, next as nextItem ${menuItem}: left-of ${nextItem} 0px aligned horizontally all ${nextItem}

ご覧のとおり、実際のチェックはそれほど複雑ではありませんが、コードはすでに直感的ではなくなっています。 テストでより類似したコードがあった場合を想像してみてください。 ある時点で、それは維持不可能な混乱になるでしょう。 それを改善する方法があるはずです。

レイアウトテストの再考

前の例を考えると、1つか2つの文でレイアウトを表現できるようです。 たとえば、次のように言うことができます。「すべてのメニュー項目は、間に余白を入れずに水平に配置する必要があります。 最初のメニュー項目は、余白なしでメニューの左側に配置する必要があります。」 必要なレイアウトを説明する文を作成したので、コードでそれらを使用できないのはなぜですか? 次のようなコードを記述できると想像してみてください。

 = Menu = |first menu.item-* is in top left corner of menu |menu.item-* are aligned horizontally next to each other

実際、それは私のプロジェクトからコピーされた実際に機能するコードです。 これらの最後の2行(パイプ|で始まる)では、これら2つのステートメントを解析することによって引数を収集するカスタム関数を呼び出しています。 もちろん、上記の例はそのままでは機能しません。 コンパイルするには、これら2つのステートメントのハンドラーを実装する必要があります。 後でこの実装に戻ります。

上記の例の重要なポイントは、レイアウトテストがオブジェクト駆動型テストから式駆動型テストに移行したことです。 このようなマイナーな例からは明らかではないかもしれませんが、より大きなスケールでは間違いなく目立ちます。 では、なぜこれが重要なのでしょうか。 簡単に言えば、これは私たちの考え方を変え、ソフトウェアの設計とテストの作成方法に影響を与えるということです。

この手法を使用すると、ページを特定の関係を持つオブジェクトの集まりとして扱うことはありません。 個々の要素のCSSプロパティはテストしません。 また、複雑で重要なコードを書くことは避けます。 代わりに、一般的なレイアウトパターンと意味のあるステートメントを考えようとしています。 メニュー項目1、メニュー項目2などを個別にテストするのではなく、次のような一般的なステートメントを適用します。

  • 他の要素で再現可能です。
  • ハードコードされたピクセル値は含まれません。
  • 具体的なオブジェクトではなく、抽象化に適用されます。
  • そして、最後になりましたが、私たちがそれらを読むとき、実際に意味があります。

使い方

この簡単な例を使用して、カスタムレイアウト式のメカニズムを説明しましょう。

簡単なスケッチ
簡単なスケッチ(拡大版を表示)

この例では、ボタンがパネルまで伸びており、左側または右側に余白がないことを確認することになっています。 カスタムルールがなくても、さまざまな方法でアプローチできますが、私は次のソリューションを好みます。

 button: inside some_panel 0px left right

上記のコードは、側面にカスタムマージンを宣言する柔軟性を提供し、ボタンがパネル内に完全に含まれていることを暗黙的にテストします。 欠点は、あまり読みにくいことです。そのため、この検証を式button stretches to some_panelます。 これを機能させるには、次のようなカスタムルールを作成する必要があります。

 @rule %{elementName} stretches to %{parentName} ${elementName}: inside ${parentName} 0px left right

それでおしまい。 これで、1行でテストに入れることができます。

 | button stretches to some_panel

ご覧のとおり、このルールはelementNameparentNameの2つの引数を取ります。 これにより、他の要素にも適用できます。 これら2つのオブジェクトの名前を置き換えるだけです。

 | login_panel stretches to main_container | header stretches to screen | footer stretches to screen # etc.

独自のテスト言語の実装

水平メニューのレイアウト式の最初の例に戻りましょう。

 = Menu = | first menu.item-* is in top left corner of menu | menu.item-* are aligned horizontally next to each other

最初のルールは次の方法で実装できます。

 @rule first %{itemPattern} is in %{cornerSides} corner of %{parentElement} @if ${count(itemPattern) > 0} ${first(itemPattern).name}: inside ${parentElement} 0px ${cornerSides}

この例で使用すると、引数は次のように解析されます。

  • itemPattern = menu.item-*
  • cornerSides = top left
  • parentElement = menu

最初の式が終わったので、次の式に移ることができます。 2番目の式では、すべてのメニュー項目の水平方向の配置をテストすることになっています。 私は3つの簡単なステップを提案します:

  1. すべてのメニュー項目を検索します。
  2. 最後から2番目の要素までそれらすべてを繰り返します。
  3. 要素nが要素n+1の左側にあり、それらの上端と下端が揃っていることを確認します。

それを機能させるには、 @forEachループとスペックleft-of alignedして配置する必要があります。 幸い、Galenでは、ループ内の前または次のアイテムを参照できます。 次の要素への参照を宣言した場合、それは最後から2番目の要素までしか繰り返されません。これはまさに必要なものです。

 @rule %{itemPattern} are aligned horizontally next to each other @forEach [${itemPattern}] as item, next as nextItem ${item}: left-of ${nextItem} 0px aligned horizontally all ${nextItem}

テストでマージン( ~ 20pxまたは10 to 20pxなど)を指定する必要がある場合はどうなりますか? 次に、別のルールを実装するか、既存のルールを拡張して%{margin}引数をサポートすることをお勧めします。

 @rule %{itemPattern} are aligned horizontally next to each other with %{margin} margin @forEach [${itemPattern}] as item, next as nextItem ${item}: left-of ${nextItem} ${margin} aligned horizontally all ${nextItem}

それでおしまい! 水平メニューの検証に役立つ一般的な式を作成しました。 ただし、柔軟性があるため、それ以上のことができます。 これを使用して、ページ上の他の要素をテストできます。 これを使用して、2つのボタンの配置をテストすることもできます。

フォームボタン
フォームボタン(拡大版を表示)
 | menu.item-* are aligned horizontally next to each other with 0px margin | submit_button, cancel_button are aligned horizontally next to each other with 20px margin

これらの2つの例で、最初の引数を2つの異なる方法で宣言していることに気付くかもしれません。 最初の式では、最初の引数は“menu.item-*”であり、2番目の式では“submit_button, cancel_button”として宣言されています。 これが可能なのは、 @forEachループを使用すると、オブジェクトのコンマ区切りリストをスター演算子と一緒に使用できるためです。 しかし、まだリファクタリングは完了していません。 コードをさらに改善して、読みやすくすることができます。 メニュー項目とログインフォームボタンのグループを作成すると、次のようなことができます。

 @groups menu_items menu_item-* login_form_buttons submit_button, cancel_button = Testing login page = | &menu_items are aligned horizontally next to each other with 0px margin | &login_form_buttons are aligned horizontally next to each other with 20px margin

この場合、グループ宣言を表す&記号を使用する必要があります。 それはすでに良いテストです。 まず、それはうまく機能し、必要なものをテストすることができます。 また、コードは明確で読みやすいです。 別の人がログインページの外観と設計要件を尋ねた場合は、テストを確認するように指示できます。

ご覧のとおり、複雑なレイアウトパターンにカスタム式を実装することはそれほど重要ではありません。 最初はやりがいがあるかもしれませんが、それでもクリエイティブな活動に似ています。

動的マージン

さまざまなWebサイトで時々見られる可能性のある別のまれなレイアウトパターンを見てみましょう。 要素間の距離が等しいことをテストしたい場合はどうなりますか? そのための別のルールを実装してみましょうが、今回はJavaScript実装を使用します。 私はそのようなステートメントを提案します: “box_item-* are aligned horizontally next to each other with equal distance” 。 要素間のマージンがわからず、ピクセル値をハードコーディングすることはできないため、これは少し注意が必要です。 したがって、最初に行う必要があるのは、最初の要素と最後の要素の間の実際のマージンを取得することです。

等距離
等距離(拡大版を表示)

そのマージンを取得したら、以前と同様に@forEachループで宣言できます。 必要なロジックはこれまでのすべての例よりも少し複雑なので、JavaScriptAPIを使用してこのルールを実装することを提案します。 my-rules.jsという名前のファイルを作成し、次のコードを入力してみましょう。

 rule("%{objectPattern} are aligned horizontally next to each other with equal margin", function (objectName, parameters) { var allItems = findAll(parameters.objectPattern), distance = Math.round(Math.abs(allItems[1].left() - allItems[0].right())), expectedMargin = (distance - 1) + " to " + (distance + 1) + "px"; if (allItems.length > 0) { for (var i = 0; i < allItems.length - 1; i += 1) { var nextElementName = allItems[i + 1].name; this.addObjectSpecs(allItems[i].name, [ "aligned horizontally all " + nextElementName, "left-of " + nextElementName + " " + expectedMargin ]); } } });

テストコードでは、次のように使用します。

 @script my-rules.js # … = Boxes = | box_item-* are aligned horizontally next to each other with equal distance

ご覧のとおり、Galen Frameworkでは、ルールを実装するときに、GalenSpecsとJavaScriptの2つの言語から選択できます。 単純な式の場合、Galen Specsの方が使いやすいですが、複雑な式の場合、私は常にJavaScriptを選択します。 JavaScriptルールについて詳しく知りたい場合は、ドキュメントを参照してください。

ガレンエクストラ

さまざまなレイアウトパターンで十分に遊んだ結果、これらのガレンルールはすべて他のテストプロジェクトに簡単に適用できることに気付きました。 それで、最も一般的なレイアウト式を独自のライブラリにコンパイルするというアイデアが得られました。 それが私がGalenExtrasプロジェクトを作成するようになった理由です。 以下は、このライブラリの機能の例です。

 | header.icon should be squared | amount of &menu_items should be > 3 | &menu_items are aligned horizontally next to each other | &list_items are aligned vertically above each other with equal distance | every &menu_item is inside menu 0px top and has width > 50px | first &menu_item is inside menu 0px top left | &menu_items are rendered in 2 column table | &menu_items are rendered in 2 column table, with 0 to 1px vertical and 10px horizontal margin | &login_form_elements sides are vertically inside content_container with 20px margin login_panel: | located on the left side of panel and takes 70 % of its width # etc …

Galen Extrasライブラリには、Webサイトで一般的に見られるレイアウトパターンの多くが含まれており、有用なパターンを見つけたらすぐに更新し続けます。 このライブラリがセットアップされたら、実際のテストプロジェクトで試してみることにしました。

メッセージングアプリのテスト

現在、私はMarktplaatsでソフトウェアエンジニアとして働いています。 ある時点で、私は得たすべての経験を実際のプロジェクトに適用することにしました。 Webサイトのメッセージングページをテストする必要がありました。 これがどのように見えるかです:

メッセージングページ
メッセージングページ(拡大版を表示)

正直なところ、そのようなページのテスト、特にレイアウトテストの実装はいつも少し怖いように思えました。 しかし、Galen Extrasライブラリを配置すると、実際には非常にスムーズに進み、すぐに次のコードを思い付くことができました。

 @import ../selected-conversation.gspec @groups (message, messages) messenger.message-* first_two_messages messenger.message-1,messenger.message-2 first_message messenger.message-1 second_message messenger.message-2 third_message messenger.message-3 (message_date_label, message_date_labels) messenger.date_label-* first_date_label messenger.date_label-1 second_date_label messenger.date_label-2 = Messages panel = = Messages and Date labels = |amount of visible &message_date_labels should be 1 |first &message_date_label has text is "17 november 2015" |amount of visible &messages should be 3 |&first_two_messages should be located at the left inside messenger with ~ 20px margin |&third_message should be located at the right inside messenger with ~ 20px margin |&messages are placed above each other with 10 to 15px margin |text of all &messages should be ["Hi there!", "I want to buy something", "Hello! Sure, it's gonna be 100 euros"] = Styling = |&first_two_messages should be styled as others message |&third_message should be styled as own message

ピクセル範囲の抽出

テストは問題ないように見えました。コンパクトで読みやすいものでしたが、それでも完璧にはほど遠いものでした。 私はそれらのマージン定義のすべてが本当に好きではありませんでした( ~ 20px 10 to 15px )。 それらのいくつかは繰り返され、それぞれが何を意味するのか理解するのは困難でした。 そのため、意味のある変数の背後にすべてのマージンを隠すことにしました。

 # ... @set messages_side_margin ~ 20px messages_vertical_margin 10 to 15px = Messages panel = = Messages and Date labels = |amount of visible &message_date_labels should be 1 |first &message_date_label has text is "17 november 2015" |amount of visible &messages should be 3 |&first_two_messages should be located at the left inside messenger with ${messages_side_margin} margin |&third_message should be located at the right inside messenger with ${messages_side_margin} margin |&messages are placed above each other with ${messages_vertical_margin} margin # ...

ご覧のとおり、余白をmessages_vertical_marginmessages_side_marginに移動しました。 また、0〜1ピクセルの範囲であるminimalマージンを宣言しました。

 # ... @set minimal 0 to 1px = Conversations Panel = | &conversations are aligned above each other with ${minimal} margin # ...

画像ベースの検証とカスタム式

ページ上のすべての主要な要素の配置をカバーしたので、スタイリングもテストすることにしました。 各メッセージの背景色がユーザーの役割に固有であることを検証したかったのです。 ユーザーがログインすると、メッセージの背景は水色になります。 他のユーザーへのメッセージの背景は白になります。 メッセージが送信されていない場合、エラーアラートの背景はピンク色になります。 これらのスタイルを検証するのに役立ったルールは次のとおりです。

 @set OWN_MESSAGE_COLOR #E1E8F5 OTHERS_MESSAGE_COLOR white ERROR_MESSAGE_COLOR #FFE6E6 @rule %{item} should be styled as %{style} message ${item}: @if ${style === "own"} color-scheme > 60% ${OWN_MESSAGE_COLOR}, 0.2 to 20 % ${MAJOR_TEXT_MESSAGE_COLOR} @elseif ${style === "error"} color-scheme > 60% ${ERROR_MESSAGE_COLOR}, 0.2 to 20 % ${MAJOR_TEXT_MESSAGE_COLOR} @else color-scheme > 60% ${OTHERS_MESSAGE_COLOR}, 0.2 to 20 % ${MAJOR_TEXT_MESSAGE_COLOR}

color-scheme仕様は、要素内の色の比例分布を検証します。 ページのスクリーンショットを切り取り、色の分布を分析します。 したがって、要素の背景色を確認するには、その分布が全色範囲の60%を超えていることを確認するだけです。 テストでは、このルールは次のように呼び出されます。

 = Styling = |&first_two_messages should be styled as others message |&third_message should be styled as own message

テストスイートの構成

メッセージングアプリは、RESTfulメッセージングAPIと連携して動作する動的アプリケーションです。 したがって、すべての異なる状態でそのレイアウトをテストするには、テストデータを準備する必要があります。 テストスイートですべてのテストメッセージを構成できるように、MessagingAPIをモックアップすることにしました。 これが私のテストスイートの断片で、テストがどのように構成されているかを示しています。

 // ... testOnAllDevices("Unselected 2 conversations", "/", function (driver, device) { mock.onGetMyConversationsReturn(sampleConversations); refresh(driver); new MessageAppPage(driver).waitForIt(); checkLayout(driver, "specs/tests/unselected-conversations.gspec", device.tags); }); testOnAllDevices("When clicking a conversation it should reveal messages", "/", function (driver, device) { mock.onGetMyConversationsReturn(sampleConversations); mock.onGetSingleConversationReturn(sampleMessages); refresh(driver); var page = new MessageAppPage(driver).waitForIt(); page.clickFirstConversation(); checkLayout({ driver: driver, spec: "specs/tests/three-simple-messages-test.gspec", tags: device.tags, vars: { expectedTextProvider: textProvider({ "messenger.message-1": "Hi there!\n11:02", "messenger.message-2": "I want to buy something\n12:02", "messenger.message-3": "Hello! Sure, it's gonna be 100 euros\n13:02" }) } }); }); // ...

虫を捕まえる

これらの単純な式を実装すると、すぐに成果が得られます。 テストスイートでどのようなバグをキャッチできるかを見てみましょう。

スタイリングの問題

これは、CSSコードベースで問題が発生し、その結果、すべてのメッセージが同じ背景でレンダリングされる場合の例です。

間違ったメッセージの背景色
間違ったメッセージの背景色(大きいバージョンを表示)

このスクリーンショットを元のスクリーンショットと比較すると、最後のメッセージの背景が白であるのに対し、水色になっていることがわかります。 Galenがこの問題をどのように報告しているか見てみましょう。

エラーメッセージ付きのスクリーンショット
エラーメッセージ付きのスクリーンショット(拡大版を表示)

ハイライトされたオブジェクトの場合、 color #e1e8f5 on “messenger.message-3” is 0% but it should be greater than 60% 。 正直なところ、このエラーメッセージはそれほど明確には見えませんが、このチェックはカスタムルールから生成されたものであるため、レポートブランチでいつでも元の名前を検索できます。

テストの失敗を報告する
テストの失敗を報告する(大きなバージョンを表示)

上にスクロールすると、元のステートメントが&third_message should be styled as own message 。 これは、カスタム式を使用するもう1つの利点です。これらは、失敗を理解し、生成されたすべての検証を適切に説明するのに役立ちます。

ポジショニングの問題

これは、要素の配置が正しくないためにレイアウトが正しくない場合の別の例です。 次のスクリーンショットでは、最後のメッセージがメッセージングビューポートの右側ではなく左側に配置されていることがわかります。

メッセージの位置が間違っています
メッセージの位置が間違っています(拡大版を表示)

エラーメッセージが表示されたスクリーンショットをもう一度見てみましょう。

メッセージの位置が間違っています
メッセージの位置が間違っています(拡大版を表示)

スクリーンショットは、メッセージングコンテナと最後のメッセージ要素を強調しています。 それとともに、次のエラーメッセージが表示されます。 “messenger.message-3” is 285px right which is not in range of 22 to 28px 。 Web開発者には、右側に22〜28ピクセルのマージンが期待される理由が明確でない場合があります。 ここでも、レポートブランチで検証ステートメントを探す必要があります。

メッセージの位置が間違っています
メッセージの位置が間違っています(拡大版を表示)

そのチェックの元のステートメントは、 &third_message should be located at the right inside messenger with ~ 25px margin 。 それははるかに理にかなっています。 さらに、他のフロントエンドエンジニアは、テストを作成していなくても、このテストレポートを理解できます。

レイアウトテストガイドライン

これらのさまざまな実験をすべて念頭に置いて、私はすべての学習を一般的なレイアウトテストガイドラインに形式化することにしました。 テストルーチンを簡単にするために従うべき手順の簡単なチェックリストを次に示します。

  • デザインのレイアウトパターンを特定します。
  • 検証ステートメントを一般化します。 ほとんどの検証を1つの文に凝縮してみてください。
  • コンポーネント化! 繰り返される要素のテストを専用のコンポーネントに移動することをお勧めします。
  • セクション、ルール、オブジェクトには意味のある名前を使用してください。
  • ピクセルは避けてください。 ピクセル値(正確な値または範囲)を意味のある変数に置き換えてみてください。
  • テストを容易にするために、Webサイトのコードを調整します。 これは、本番コードとテストコードの両方を構造化して維持するのに役立ちます。

救助への受け入れ基準

「では、レイアウトテストはどの程度詳細にすべきでしょうか。 そして、具体的に何をテストする必要がありますか?」 一般的な答えを出すのは難しいです。 問題は、テストの対象範囲が狭い場合、バグを見逃してしまうことです。 一方、テストが詳細すぎると、誤検知が多くなり、将来的にはテストのメンテナンスで迷子になる可能性があります。 したがって、トレードオフがあります。 しかし、私は自分自身のための一般的なガイドラインを理解しました。 作品をより小さなユーザーストーリーに分割すると、受け入れ基準の形でページのデザインを構成することがより簡単になります。 結局、この非常に受け入れられる基準をテストコードに正しく入れることができます。 たとえば、これらのステートメントの一部は、前のすべてのコード例に示されているように、カスタムルールの形式で定義できます。 受け入れ基準の良い例は、次のようなものです。

  • ポップアップは、画面の垂直方向と水平方向の中央に配置する必要があります。
  • 幅は400ピクセルである必要があります。
  • ボタンは水平に配置する必要があります。
  • 等々

デザインを簡単な文章で説明すると、それらを再利用可能なステートメントに変換したり、テストコードを整理したりするのが簡単になります。

結論

ご覧のとおり、このような演習は、デザインを構造化し、複数のページコンポーネント間で共有できる一般的なレイアウトパターンを見つけるのに役立ちます。 ページが複雑で多くの要素で構成されている場合でも、レイアウト式でそれらをグループ化する方法をいつでも見つけることができます。 このアプローチにより、レイアウトテストはテスト駆動開発のためのツールになり、ソフトウェアを段階的に設計、実装、および提供するのに役立ちます。これは、アジャイル環境で特に役立ちます。

資力

  • ガレンフレームワーク(公式サイト)
  • Galen Framework、GitHub
  • Galen Extras(ライブラリ)、GitHub
  • Galen Bootstrap、GitHub
  • 「GalenFrameworkTutorials」、YouTube