SeleniumでのExt.Jsプロジェクトのテスト

無限にできることは3つあります。

1.火傷を見る

2.水の流れを見る

3.そして、誰かがどのように機能するかを見る



私たちの場合、9000以上のテストがスピンするのを見てください。 セレンのテストは特に美しく見えます。 システムをテストするために内部に永続的なモーションマシンを備えた猛烈なジャーボアのように見えます。



あなたについては知りませんが、それは私を引きずります:





残りの記事では、Seleniumでのテストどのよう編成したかについて、少しサクセスストーリーを紹介します。





これは、発射体に対する2番目のアプローチでした。 2009年に初めて、すべてが雨になりました。

•WebドライバーはIEでのみ機能しました。

•ブラウザを開くとフリーズすることがあります

•時々ブラウザを閉じることができませんでした

•そして最も重要なこと:ブラウザー拡張機能(いわゆる「スティッキング」)を介した組み込みテスト記録は、Ext.Jsシェルのテストを貧弱にしました。



私たちのプロジェクトは、Ext.Net-.NET用Ext.Jsシェルを使用して記述されています。 そして、Ext.Jsは明らかにSeleniumにとって複雑すぎました。 彼はクライアントの要素のランダムな識別子を生成し、さらにオブジェクトのランダムな識別子を生成しました(これはプラットフォームの並列処理と高負荷に必要です)。



テストはマウスで簡単にクリックできるようですが、このテストの寿命は数日でした。 さらに悪いことに、テストが落ちたときに、何度も再投稿するよりも、転倒の理由を理解するのが難しいことがよくありました(これは数回行われました)。



そして、テストは遅かったです! シナリオを想像してください:

1.検索文字列をデータテーブルに挿入します

2.サーバーは応答を返します-空のグリッド(正しい場合もあります)

3.その後、発生した場合はエラーメッセージを送信します。



任意のクリックに対する非同期リクエストを含むExt.Jは、多くの呼び出しで10秒のエラーメッセージを待つ必要があるように設計されており、受信しなかった場合、検索は正常に機能すると考えました。

ここで10秒、そこに10秒、結果として、テストの90%の時間は待機で構成されます。



それだけではありません。 Seleniumログから貼り付けられたテストが失敗した理由を理解しようとしましたか? そのため、テストを再度実行するのではなく、ログを見て問題の本質を理解します。 うまくいきませんでした。



数ヶ月後、そのようなテストは私たちが行うよりも時間がかかることが明らかになり、Seleniumテストを終了しました。



その間、プロジェクトは成長し、機能の数は数千単位で測定されました。そして、1年前、英雄的なセルマリルは更新されたSeleniumとExt.Jsのテスト方法の更新された理解でこの問題に戻りました



彼の解決策は、APIを作成することでした。



マウスによるテストの記録を放棄することにしましたが、フォームに短い表記でNUnit(!)テストを書く機会に来ました。

1.作成日=今日でユーザーをフィルターします。

2.名前で並べ替え

3.最初のエントリを開きます

4.パスワードを変更します。

5.保存します。

6.「Are you sure」ウィンドウが表示されたら、「OK」をクリックします。



これを行うには、SeleniumとNUnitを介したAPIが必要でした。これ自体は非常に単純な要素で構成されますが、マウスとDOMモデルではなく、Ext.Jsインターフェイスオブジェクトで操作できます。



1か月の努力と、APIの最初のバージョンが登場しました。

サンプルテストは次のとおりです。
/// <summary> /// DocumentOperationGridOperationTest /// </summary> [Test] public void DocumentOperationGridOperationTest() { var baseDocName = typeof(BaseInDocument).ModelName(); var implDocName = typeof(BaseInDocumentImpl).ModelName(); using (var grid = Env.Navigation.OpenList(implDocName)) { var operationCaption = "_"; grid.Toolbar.Click(operationCaption); var docForm = Env.TabPanel.GetForm(implDocName); docForm.Toolbar.Click("", "  {0}".FormatWith(operationCaption)); docForm.Close(); } using (var grid = Env.Navigation.OpenList(baseDocName)) { var operationCaption = "_"; grid.Data.First().Select(); grid.Toolbar.Click("", operationCaption); grid.Toolbar.Click(""); var docForm = Env.TabPanel.GetForm(implDocName); var fieldValue = docForm.GetField<TextField>("SomeNewField"); Assert.False(string.IsNullOrEmpty(fieldValue.GetValue()), "         ,        "); grid.DeleteFirstRow(); docForm.Close(); } }
      
      









そして、これがAPI実装の外観です
  /// <summary> ///      /// </summary> /// <param name="fieldName">   ,          </param> /// <param name="buttonCaption">    ,      (  )</param> /// <returns>    </returns> public IToolbarElement GetContextMenuItem(string fieldName, string[] buttonCaption) { var buttonsFullPath = Oreodor.Utils.EnumerableExtensions.ToString(buttonCaption, "->"); Env.AddHistory("         Id - SysName = {0} - {1},   {2},   '{3}'".FormatWith( Id, this.Data.ContainsKey("SysName") ? this.Data["SysName"] : string.Empty, fieldName, buttonsFullPath)); IToolbarElement menuItem = null; if (buttonCaption.Length > 0) { var menuItems = new List<IToolbarElement>(); if (IsContextMenuVisible(fieldName)) { menuItems.AddRange(GetCurrentContextMenu()); } else { menuItems.AddRange(ShowContextMenu(fieldName)); } menuItem = Toolbar.CheckItem(menuItems, buttonCaption[0]); if (buttonCaption.Length > 1) { for (var i = 1; i < buttonCaption.Length; i++) { var menuCaption = buttonCaption[i - 1]; var itemCaption = buttonCaption[i]; var menu = menuItem.Menu.ToList(); Assert.That(menu.Count() != 0, " '{0}'    , ..      '{1}'.".FormatWith(menuCaption, itemCaption)); var candidateToolbarItem = Toolbar.CheckItem(menu, itemCaption); Assert.That(candidateToolbarItem != null, "   '{0}'   '{1}'.   : {2}".FormatWith(itemCaption, menuCaption, menu.Aggregate(", ", (aggregated, item) => aggregated + "'" + item.Text + "'"))); menuItem = candidateToolbarItem; } } } return menuItem; }
      
      









重要な問題も解決されました-TeamCityログからのエラーの迅速な理解。 Apiはテストごとにこのようなレポートを生成します。



結論:システムインターフェイスの動作の約80%をカバーしました。 SeleniumでExt.Jをテストするには、次の問題を解決するためにテスト用の独自のラッパーを作成する必要があります。

1.テストの簡潔さと明確さ

2.システムを変更するテストの安定性

3.テストの速度

4.テストの内訳の理由を理解するのは簡単です。

ブラウザインターフェイスから貼り付けて作成されたテストは、ほとんどの場合あなたに合わないでしょう。



PS

Ext.Jsプロジェクトがあり、それをSeleniumテストでカバーすることに決めた場合は、アドバイスを求めて助けてください。



All Articles