Selenium は人気のある UI テスト ライブラリですが、これに基づいて作成されたテストには脆弱性や信頼性の低さなどの一般的な問題があります。 InfoQ は、Selenium 上に作成された F# ライブラリである Canopy について詳しく知るために、Canopy の作者 Chris Holt 氏にインタビューを実施しました。
Chris Holt: canopy は、Selenium に基づいて F# で実装された機能の層であり、その目標は、UI テストの動作をユーザーの期待に応えることです。 Selenium は優れたパフォーマンスを発揮しますが、時々硬すぎるように見えることがあります。 canopy では、要素をクリックできないため、すべての動作がすぐにエラーを報告することはなくなり、適切な時間が経過しても要素をクリックできないまで継続的に要素をクリックしようとした後にエラーが報告されます。これにより、最初の試行でしか成功しない傾向にあるテストではなく、より信頼性の高いテストを作成することができます。
CH:canopy には、要素の取得や画面上のユーザーの動作を含むリトライ機能と検証機能が組み込まれています。さらに、キャノピーは、実用的なエラー メッセージを通じて、特定のセレクターのスペル ミスなどの一般的な問題をユーザーが修正するのにも役立ちます。また、さまざまな方法で要素を選択することもサポートされており、これらの機能は簡単に拡張できます。
たとえば、ユーザーの画面に「保存」というテキストのボタンがある場合、クリックする目的を達成するにはコードに「保存」をクリックするだけで済みます。通常の Selenium コードでは、ユーザーは ByText、ById、ByCSS、ByXPath、およびその他のメソッドの中から選択する必要があります。この機能を拡張したい場合は、フォーム データ内のプレースホルダー値や、メタデータを表すために人為的に定義された data-* タグなど、Web ページのユーザーの通常のメソッドに対応するファインダー実装を追加するだけで済みます。
canopy は、ユーザーがテストを読み書きしやすくするための一連の簡潔な API も提供します。 HTML のさまざまな違いを克服することもできます。たとえば、各入力タイプは HTML では異なる方法で表現されるため、生の Selenium を通じて異なる方法で操作されます。キャノピーでも操作方法は同じです。例:
// Assign a value to a textbox or dropdown"#state" << "New York"
CH: はい、Selenium でサポートされている機能であれば、canopy もサポートしています。 Browserstack をサポートするには、ユーザーは RemoteWebdriver を使用する必要があります。キャノピー自体に多くのリトライ機能が組み込まれているため、インタラクションの数は増加します。ただし、ユーザーは Sleep を頻繁に呼び出す必要がないため、この対話の増加は許容されます。 canopy は、canopy にセレクター タイプを分析させるのではなく、セレクター タイプを具体的に表現する場合に適用できるオプションの最適化も多数提供します。
CH: UI オートメーションで使用される「トリック」のほとんどは、要素の選択に関連しています。適切なセレクターを使用する必要があるか、それともクラスや ID などの属性をタグに追加する必要があるかについては、この 2 つの間のバランスを見つける必要があります。私の意見では、CSS および JQuery セレクターの構文は最高であり、ユーザーは 80 ~ 90% のシナリオでこの方法を使用できます。 XPath は残りの 10% ~ 20% のシナリオで使用できます。 XPath は、テキストの正確な一致や要素の親要素の検索に必要です。上記の例で「保存」をクリックすると、内部実装では XPath が使用され、値または内部テキストで検索することもでき、非常に便利です。
一定期間練習すると、ユーザーはセレクターの作成方法を熟練できるようになります。セレクターを生成するために何らかのツールを使用するのではなく、練習を通じて学習することをお勧めします。このアプローチはより正確で、ユーザー テストに影響を与える形でページ構造が変更された場合の修正が容易です。ユーザーがセレクターについて一定の経験を積めば、HTML コードの保守を容易にする方法を理解できるようになり、セレクターの作成が簡素化されます。
セレクターは、理解しやすいようにいくつかの方法で記述することができます。たとえば、#header.links セレクターは、ページのヘッダー div 内のすべてのリンク要素を表します。自動生成された XPath では、html/body/div/div/div[2]/ul/li/a となる場合がありますが、これは意味を理解するのに役立ちません。この選択チェーンで div を追加または削除すると、セレクターは機能しなくなります。 CSS で記述されたセレクターは、誰かがヘッダー ID を変更するか、リンク クラスを削除/変更しない限り、「常に」有効です。
CH:canopy目前 内置了3种reporter实现,即ConsoleReporter、TeamCityReporter和HtmlReporter。如果用户需要新增一个自定义的功能,只需简单地实现IReporter这个接口就行了。
1)通过实现IReporter接口, 自定义测试结果的输出。
2) 在canopy所使用的finder集合中 添加新的通用finder实现,以帮助用户找到页面元素。
3) 为用户常用的action添加新的函数。由于F#会运行某个函数最新定义的版本,因此用户还能够“重写”现有的函数,以满足自身的需求。
比方说,用户可以实现自定义的“click”功能,只需创建一个模块,例如“canopyExtensions”,并在“打开canopy”操作后“打开”这一模块,将所有扩展方法与重写的方法定义在其中。这样一来,所有测试都会调用由用户所定义的功能,而无需改动任何现有的功能。
这个示例表现的是某人希望能够在多选框中实现对元素的Ctrl+Click操作。由于canopy本身不具备这一特性,因此作者编写了一段扩展方法。
4) canopy并没有隐藏任何Selenium中的特性,或是对其进行抽象化。它只是使用了IWebDriver与IWebElement接口。用户在Stackoverflow网站上看到的各种问题与回复对canopy都是100%有效的。用户所要做的唯一一件事就是将代码转换为F#。
CH:测试的运行方式是执行由构建过程所生成的控制台应用。测试结果支持不同的 输出格式。支持TeamCity的配置过程只需一行代码:
reporter <- new TeamCityReporter() :> IReporter
我个人会选择使用一些简单的任务来实现整个构建过程,因此我在TeamCity中创建的任务都是很简单的,例如从源代码控制系统中获取最新代码,随后通过一个命令行语句启动我的任务,并完成其余工作。
在Jenkins环境中,我会选用HtmlReporter,通过一个Jenkins的插件生成html文档,并保存到整个任务的结果中。这同样也可以通过简短的几行代码完成设置工作。
canopy是一个托管在 GitHub上的开源项目。如果读者有兴趣了解对它的更多介绍,可以观看Chris Holt最近 在fsharpConf大会上关于canopy的演讲。
查看英文原文: UI Testing in F# with canopy