Seleniumの小さいながらも非常に便利なパッチ

小さいながらも非常にダイナミックな会社では、毎日100を超えるタスクがテストされています。 それらはすべて、テスト環境と実際の環境に近い環境の両方でテストされます。 Web関連のタスクの大部分は、自己テストによってチェックされますが、これには多くの機能があります。







約6か月前、非常に多くのテストとタスクがあったため、ラッシュアワーのSeleniumを備えた小規模ファームは、新しいFirefoxまたはChromeセッションのリクエストから文字通り「drれ」始めました。 これは次のようなものです。無料のブラウザを待っているセッションからSeleniumグリッド上にキューが形成されます。 ユーザーは引き続き自動テストを実行し、このキューは拡大し続けますが、ブラウザーは古いタスクでビジーであり、セッションはタイムアウトで「フォールオフ」します。













当時、Firefox、Chrome、Internet Explorer、PhantomJSで共有されたノードの最大数は約200でした。私が発生した問題の解決策の1つは、テストを実行する前に空きノードの数を追跡し、セットアップメソッドでテストを「保留」することでした()、空きノードでは十分ではありません。







変更の説明で、Seleniumは一時的に、HTTP要求を使用してグリッドから情報を受信する機能をスキップしました。 利用可能なコマンドは、HubStatusServlet.javaサーブレットコードで直接表示できます 。 それらの3つだけがあります: configurationslotCounts (スロットの数)およびnewSessionRequestCount (ブラウザーを受信するためのキュー内のセッションの数)。







リクエストの形式はかなりトリッキーです。これはGETリクエストですが、本文があります。 実験のために、cURLを使用して、これらのコマンドが返すことを確認します。







$ curl -XGET http://selenium1:5555/grid/api/hub -d '{"configuration":[]}'
      
      





 { 'success': true, 'port': '5555', 'hubConfig': '/usr/local/selenium-rc/grid.json', 'host': 'selenium1.d3', 'servlets': 'org.openqa.grid.web.servlet.HubStatusServlet', 'cleanUpCycle': 5000, 'browserTimeout': 120000, 'newSessionWaitTimeout': 30000, 'capabilityMatcher': 'org.openqa.grid.internal.utils.DefaultCapabilityMatcher', 'prioritizer': null, 'throwOnCapabilityNotPresent': true, 'nodePolling': 5000, 'maxSession': 5, 'role': 'hub', 'jettyMaxThreads': - 1, 'timeout': 90000 }
      
      





 $ curl -XGET http://selenium1:5555/grid/api/hub -d '{"configuration":["slotCounts"]}'
      
      





 { 'success': true, 'slotCounts': { 'free': 50, 'total': 196 } }
      
      





 curl -XGET http://selenium1:5555/grid/api/hub -d '{"configuration":["newSessionRequestCount"]}'
      
      





 { 'success': true, 'newSessionRequestCount': 3 }
      
      





SeleniumのすべてのテストはPHPで記述されており、同様のリクエストは次のようになります。







 <?php $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'http://selenium1:5555/grid/api/hub'); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($curl, CURLOPT_POSTFIELDS, '{"configuration":["slotCounts"]}'); curl_exec($curl);
      
      





原則として、スロットの合計数と待機中のセッションの数をsetUp()テストメソッドに要求することで、待機を開始できます。 ただし、異なるブラウザにリソースを不均等に割り当てている場合、これはあまり便利ではありません。 たとえば、Google Chromeの約3分の1のFirefoxノードがあります。 また、Internet ExplorerとMS Edgeが占有するノードは約10個だけです(バージョンごとに分割することもできます)。 Selenium Gridによると、まだ空きノードが残っているとのことですが、Chrome専用の空きノードはなくなっている可能性があります。







そのため、サーブレットの機能を追加して、使用可能なブラウザの数とブラウザを理解する必要がありました。 パッチ自体はそれほど大きくありません。そのコードは次のとおりです。







 diff --git a/java/server/src/org/openqa/grid/web/servlet/HubStatusServlet.java b/java/server/src/org/openqa/grid/web/servlet/HubStatusServlet.java index 8b9c578..550c5db 100644 --- a/java/server/src/org/openqa/grid/web/servlet/HubStatusServlet.java +++ b/java/server/src/org/openqa/grid/web/servlet/HubStatusServlet.java @@ -29,10 +29,12 @@ import org.openqa.grid.internal.Registry; import org.openqa.grid.internal.RemoteProxy; import org.openqa.grid.internal.TestSlot; +import org.openqa.selenium.remote.CapabilityType; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -128,6 +130,11 @@ private JsonObject getResponse(HttpServletRequest request) throws IOException { paramsToReturn.remove("slotCounts"); } + if (paramsToReturn.contains("browserSlotsCount")) { + res.add("browserSlotsCount", getBrowserSlotsCount()); + paramsToReturn.remove("browserSlotsCount"); + } + for (String key : paramsToReturn) { Object value = allParams.get(key); if (value == null) { @@ -169,6 +176,53 @@ private JsonObject getSlotCounts() { return result; } + private JsonObject getBrowserSlotsCount() { + int freeSlots = 0; + int totalSlots = 0; + + Map<String, Integer> freeBrowserSlots = new HashMap<>(); + Map<String, Integer> totalBrowserSlots = new HashMap<>(); + + for (RemoteProxy proxy : getRegistry().getAllProxies()) { + for (TestSlot slot : proxy.getTestSlots()) { + String + slot_browser_name = + slot.getCapabilities().get(CapabilityType.BROWSER_NAME).toString().toUpperCase(); + if (slot.getSession() == null) { + if (freeBrowserSlots.containsKey(slot_browser_name)) { + freeBrowserSlots.put(slot_browser_name, freeBrowserSlots.get(slot_browser_name) + 1); + } else { + freeBrowserSlots.put(slot_browser_name, 1); + } + freeSlots += 1; + } + if (totalBrowserSlots.containsKey(slot_browser_name)) { + totalBrowserSlots.put(slot_browser_name, totalBrowserSlots.get(slot_browser_name) + 1); + } else { + totalBrowserSlots.put(slot_browser_name, 1); + } + totalSlots += 1; + } + } + + JsonObject result = new JsonObject(); + + for (String str : totalBrowserSlots.keySet()) { + JsonObject browser = new JsonObject(); + browser.addProperty("total", totalBrowserSlots.get(str)); + if (freeBrowserSlots.containsKey(str)) { + browser.addProperty("free", freeBrowserSlots.get(str)); + } else { + browser.addProperty("free", 0); + } + result.add(str, browser); + } + + result.addProperty("total", totalSlots); + result.addProperty("total_free", freeSlots); + return result; + } + private JsonObject getRequestJSON(HttpServletRequest request) throws IOException { JsonObject requestJSON = null; BufferedReader rd = new BufferedReader(new InputStreamReader(request.getInputStream()));
      
      





すべてのルール(テストなど)で正式化せず、SeleniumHQに送信しなかったことは、まだ少し恥ずかしいです。 読者がこの機能を便利だと思ったら、近い将来それをやると約束します:)







Seleniumソースのローカルコピーにパッチを適用し、Selenium-gridの独自のアセンブリをアセンブルします( 詳細なアセンブリ手順はここにあります )。 アセンブリをいじりたくない場合は、既に組み立てられているものを試すことができます: https : //github.com/leipreachan/misc_scripts/tree/master/blob/selenium







次に、selenium-gridを再起動して、返される値を確認します。







 curl -XGET http://selenium1:5555/grid/api/hub -d '{"configuration":["browserSlotsCount"]}'
      
      





そして結果:







 { 'success': true, 'browserSlotsCount': { 'IEXPLORER': { 'total': 4, 'free': 3 }, 'FIREFOX': { 'total': 95, 'free': 50 }, 'MICROSOFTEDGE': { 'total': 1, 'free': 1 }, 'PHANTOMJS': { 'total': 20, 'free': 20 }, 'CHROME': { 'total': 76, 'free': 75 }, 'total': 196, 'total_free': 149 } }
      
      





これで、Selenium Gridに含まれる無料のブラウザとその数がわかりました。 setup()メソッド(または同様の)を少し修正するために残っています:









個人的には、ラッシュアワーでのセレンのテストは少し遅いように見えましたが、はるかに安定しています。 数百のテストが自動的に実行されていることを考慮すると、テストに関わるすべての人の生活が大幅に簡素化されました。










アルチョム・ソルダトキン

BadooのリードQAエンジニア








All Articles