2013年2月20日水曜日

PlayのアプリをSelenium2でテスト

やられた…
PlayとSeleniumって仲ええんやん…
最初からPlayの中にSeleniumいてるんやん…orz
しかしいざ本体のプロジェクトの中で以前と同じようにテストを作る→jUnit Test

…なんか真っ赤になってるー

妙なエラー吐いてテストしてくれなくなりましたorz

Playのアプリ本体にテストを入れ込む

A. エラーの原因


要するに「テストプロジェクト」を別に立てずに一括で管理したいなー(チラッ という要望から入り込んだ今回の泥沼.. 冒頭の通りただ本体に放り込んだら…
java.lang.NoSuchMethodError: org.apache.http.conn.scheme.Scheme.<init>(Ljava/lang/String;ILorg/apache/http/conn/scheme/SchemeSocketFactory;)V
 at org.openqa.selenium.remote.internal.HttpClientFactory.getClientConnectionManager(HttpClientFactory.java:59)
 at org.openqa.selenium.remote.internal.HttpClientFactory.<init>(HttpClientFactory.java:48)
 at org.openqa.selenium.remote.HttpCommandExecutor.<init>(HttpCommandExecutor.java:117)
 at org.openqa.selenium.remote.service.DriverCommandExecutor.<init>(DriverCommandExecutor.java:46)
 at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:165)
 at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:107)
 at SampleTest.setUp(SampleTest.java:21)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
 at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
 at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

長い・・・
正直1行目しか読んでない.
「そんなメソッド知らねーよ( ・A・)=Cく ´Д`;)」とか言われたので何か足りないのかと考えて探し回った挙句たどり着いた答えがここの一番下の書き込み.
なんかダブって競合してんじゃね?
Playのバージョンに依るのかはわからないけど, Playプロジェクト作成時, なにやらファイルをいくつかダブらせてパスをお通しになるらしい.(尚この時点での使用verは2.1-RC1)
なのでビルドパスから外してやりましょう. ※1
外すのは
commocs-codec.jarの1.3
htmlclient.jarの4.0.1
httpcore.jarの4.0.1
もちろん他との兼ね合いも考慮すべきだろうけど, 今回はこの3つにverのこだわりは無いので古いほうをカット.

これでOK.

B-1. 実験(適当なPlayプロジェクトの作成)

実際に試してみた Playも最新2.1.0にアップデート
まずは適当にPlayプロジェクト作成→eclipseプロジェクトにする.
プロジェクトを作りタイところでcmdを開き
play new SeleniumTest
ちょっと長いけど前にまとめて?いるので今回はさらっと
SeleniumTestなる適当なプロジェクトを作成. cdコマンドかなんかで作ったプロジェクトに入ってから
play eclipse
eclipseプロジェクトとして認識してもらえるようにする.
ついでに
play run
して走らせておく. でないとテストできない(・ω・`)
これで localhost:9000 にPlayのチュートリアルを表示し続けるアプリが起動しているはず.
走らせたら今度は eclipseでプロジェクトを importする.

B-2. 実験(テスト作成)

importに成功したらまずやるのはビルドパスの修正. 上に述べたとおり余計なパスを削除する.
プロジェクトのビルドパスを開き,
commocs-codec.jarの1.3
httpclient.jarの4.0.1
httpcore.jarの4.0.1
の3つを探して Removeする. 数が多くて目が痛くなる…('A`)

削除したらテストコードの作成
testディレクトリなんて折角作ってくれているしここに入れましょう. (play testコマンドに反応するので注意)

テストコードはシンプルに
public class SampleTest {

  WebDriver driver;
  String url = "localhost:9000";

  @Before
  public void setUp() throws Exception {
    driver = new FirefoxDriver();
    driver.get(url);
  }

  @After
  public void tearDown() throws Exception {
  }

  @Test
  public void test() {
    assertTrue(driver.getPageSource().contains("Welcome"));
  }
}

ただ localhost:9000をFirefoxで開いて 「Welcome」の文字列が表示されているかのテスト.

B-3. 実験(実行)

コードができたら 実行→jUnit test.

ようやっと走ってくれました.







無駄に遠回りしたのにまとめると実は3行でおkレベルだったときの疲労感…('A`)疲れた




※1 : 02/26追記 : だからといって全部が全部「ダブってんじゃね?」とか疑うのはやめましょう. まずはほんとに無いのか確かめましょう. 地獄を見ます('A`)

0 件のコメント:

コメントを投稿

AWS CDKで立てたEC2インスタンスのTimeZoneとかいじりたかった話

EC2を立てることはできたけど、立てたインスタンスは UTCのままだし設定ファイルとかいちいちscpしてくるのはダルい。 当初UserDataでなんとかしようとしたものの、「書く量がヤバいしメンテしにくい」と悩んでいたところ見かけたのが  AWS::CloudFormation:...