Seleniumでブラウザテストを自動化!Javaでブラウザを動かそう!
今回はブラウザテストについてお話ししようと思います。
以前記事で書いた「診断コンテンツ」がありましたが、結局これはReactを使ってもっとボリュームのあるものを現在開発しています。
ただ、診断コンテンツのように選択肢によって結果が変わるものには「テスト」が必要。
しかし、今回開発しているのは「2つの選択肢がある設問が9個」で選んだ選択肢によって結果が分かれる、というもの。
つまり単純に考えると「2の9乗=512通り」のパターンがあることになります。
「こりゃあえらいこっちゃ…」
512通りを全て確認するのはかなり大変ですよね。
現在完璧に全部をテストできる状態にはなっていないのですが、Seleniumを使ってブラウザテストを初めてやってみたので備忘録として残しておきたいと思います。
Seleniumとはなんぞ???
Seleniumとは、UIテストツール、というかブラウザで表示されている要素を直接触れることなくスクリプトで操作できるツールです。
RubyやPythonなど様々な言語で利用できるものですが今回は昔少しだけ触ったことのあるJavaを使ってみました。
では早速ですが、Seleniumで操作することのできる簡単な例をご紹介したいと思います。
String url = ""; String type = ""; try { url = "https://www.yahoo.co.jp/"; } catch (UnknownHostException e) { e.printStackTrace(); } WebDriver driver = new ChromeDriver(); driver.get(url);
こちらを動かすと、自動的にGoogleChromeで「yahoo」のHPが表示されます。 こちらのコードは簡単ですが、基本となるものなのでしっかり抑えておきましょう。 まず重要になるのは「WebDriver」です。 WebDriverはなんとなくのイメージとしてブラウザに繋げるためのオブジェクトと捉えていただければ大丈夫かと思います。 そしてこのWebDriverという型でブラウザのdrverをnewしてインスタンスを作るわけなのですが、このインスタンス化によってどのブラウザを使うか、ということを選ぶことができます。 今回使用したのは「GoogleChrome」なので「ChromeDriver」をnewしてdriverインスタンスを作っています。 このインスタンス化をすることによってWebDriverがもつメソッドを利用することができるんですね。 上の例で使っているメソッドは「get(URL)」というメソッドで、これは引数のURLを開くメソッドです。 そのため、上の例ではyahooのURLが入っているのでこれを実行するとyahooのHPが表示される、というわけです。 このようなメソッドは他にもあり、WebDriverインスタンスを作ることで表示されている要素を検索して取ってきたり、要素をクリックできるようになったりします 。 さて、今回やりたいことは「512通り」ある選択肢を漏れなくテストしたい、というもの。 テスト内容としては、結果ページで出た「タイプ名」と、条件とした選択肢通りにクリックしてそのタイプになるかを確認したい。 となると、まずは2の9乗のパターンを全部吐き出すような処理を書かなければいけません。 ここで、今回行うテストの想定は - 1か0で判断してどちらの選択肢をクリックするかを決める - 2の9乗なので、「512」になるまで2進数で9桁の文字列を配列で作る というようなことを考えました。 開発している診断コンテンツは「右」か「左」のどっちを押すか、というようなものですので0か1で判断することはもちろん可能です。 では512通りの選択肢を試すためには何が必要か、と考えた時に2進数で512になるまで一つ一つの数字を2進数で表す、という考えに至りました。 先に512 までの2進数を表示するためのメソッドを載せておきます。
public String arrayCreate(int index) { List<String> decimal_array = new ArrayList<>(); // 二進数の配列を作成 for (int i = 0; i < 30; i++) { String decimal = Integer.toString(i, 2); String decimal_fill = String.format("%09d", Integer.parseInt(decimal)); decimal_array.add(decimal_fill); } return decimal_array.get(index); }
こちらはStringで引数に指定されたインデックス番号の文字列(2進数)を返すメソッドとなっています。 やっていることは非常にシンプルで、for文の「i」を1から30まで一つづつ「toString」で2進数化し、その進数を9桁の数字になるようにString.formatで整形して返す、というもの。 そしてテストするメソッドはこちらです。
public static String ClickHandler2(String args) { String url = ""; String type = ""; // IP取得 try { InetAddress address = InetAddress.getLocalHost(); url = "http://" + address.getHostAddress() + ":8888"; } catch (UnknownHostException e) { e.printStackTrace(); } WebDriver driver = new ChromeDriver(); WebDriverWait wait = new WebDriverWait(driver, 20); driver.get(url); WebElement start = driver.findElement(By.className("start-btn")); start.findElement(By.tagName("a")).click(); if (driver.findElements(By.tagName("button")).size() != 0) { System.out.println(args); for (int z = 0; z < 10; z++) { if (driver.findElements(By.tagName("button")).size() != 0) { List<WebElement> el = driver.findElements(By.tagName("button")); WebElement el0 = el.get(0); WebElement el1 = el.get(1); switch (args.charAt(z)) { case '0': el0.click(); break; case '1': el1.click(); break; } } else { System.out.println("結果ページです"); WebElement h1 = driver.findElement(By.tagName("h1")); String src = h1.findElement(By.tagName("img")).getAttribute("src"); type = src.substring(src.length() - 5, src.length() - 4); System.out.println(type); } } } return type.toUpperCase(); }
このメソッドは先ほどのarrayCreateで返された二進数の文字列を引数にして、その文字列が「0か1か」で9問目まで判別し、その判別結果によってボタンをクリックさせる、という内容になっています。 最終的に返されるのはtypeというString型の変数で、こちらが結果ページの「タイプ」です。 そしてテストケースはこちら。
@Test public void test0() { Assert.assertEquals("R", ClickTest2.ClickHandler2(arrayCreate(0))); }
予想されるタイプを第一引数、そして先ほどのメソッドで返されるタイプを第二引数にしています。 現在テストケースはこれしか作成していませんが、なんとなく512まで作れそうな気だけはするような… それぞれのメソッドに関してはまた後日お話しします。 今回は初めてSeleniumを使ってみたら意外といろんなことができるんだなあ...というお話しでした!