2015/12/24 このエントリーをはてなブックマークに追加 はてなブックマーク - KotlinのSeleniumライブラリKebabを作ってる #ktac2015 #jkug

KotlinのSeleniumライブラリKebabを作ってる #ktac2015 #jkug

カテゴリ: , , , ,




こちらはKotlinアドベントカレンダー2015の24日目の記事です。





みなさん、Kotlin書いてますか?興味ありますか?
多分、どちらかの人がこのアドベントカレンダーを見てくれているのだと思います。

2014のKotlinアドベントカレンダーにも参加させていただきましたが、
ほんとにKotlin人口がここ1年で急激に増えて感慨深いものがあります(しみじみ)


今回のブログはgebインスパイア系のKebabというライブラリを作っているっていう話です。

https://github.com/yyYank/Kebab




名前は適当ですが、ケバブだと美味しそうですよねw
はい!…はい。








今回の作るきっかけは


・KotlinのネタはみんなAndroidに偏るだろう
・WebDriverが野暮ったいのは知ってる
・Groovy製のgebが話題になってるのは知ってるけど便利そうだから素直に使いたくない(あまのじゃく)
・Kotlinで似たようなもん作れるんじゃない?
というところです。

gebばりの利点、Page Objectパターンぐらいは出来るようにライブラリとして仕上げたいなというのが目標。
さらに発展させて、Kotlinの良さにより何かを生み出せれば良いよなぁと。



こんな感じでやれんか!!っという気持ちでやってみることにしました。
class KebabTest {
    val kebabConfEnv : String by Delegates.notNull()
    val kebabConfScript : String by Delegates.notNull()
    private val browser = Browser()


    fun test() {
        browser.drive("http://localhost:8080/jkug", {
            // これがやりたいんだがなかなか大変
            // 画面が表示されていること
            assertEquals(title == "Hello Kotlin")
            // テキストボックスに「JKUG」と入力
            $("form").username = "JKUG"
            val sendButton = $("input", name:"send")
            sendButton.click()
        })
    }
}





・gradle init
・build.gradleの編集
・gradle build
・IntelliJ IDEA CEでプロジェクトを開く
・ゴリゴリ実装




一応ブラウザ開いてGoogle見に行くぐらいまでは出来た。

git cloneしてもらって、ChromeDriverをダウンロードしてKebab/driver/配下に置く。
んで、KebabTestというクラスがあるのでrunしてもらえば以下のような動きします。
※動作環境はMax OS X。Winでも動くけど








そして、jQuery likeな記法ですが…










そもそもKotlinあかんかったw

シンタックスエラーになってしまいました。
よくよく考えてみれば、このjQuery的な省略記法ですが
KotlinのJavaScript Runtimeでも「$」ではなく「jq」関数としてたくさん用意しているのでした。
やるとすれば、同じようにjq関数として関数を提供するのが落としどころですかね。







全部。(これはひどい)
ネタと思ってください。実用性はもっと本気出して費やさないとまだまだです。


ホントは最低限画面テストの動作が出来るところまで持って行きたかったのだけど、
なかなか時間と僕の技術的にアレでした。。。


Kotlinらしさというところで言えば、
・関数を=で受ける
・constructor
・functionリテラル
・Delegates.notNull
・Null Safty


とかですかね。
Delegates.notNullは逃げだなぁと思いつつ、
判断難しいところはコンパイル通すためにグワーって使っちゃいました。


グワーって書いた割にはステップ数少なくて
さすがKotlinだなぁって感じです。


2015/12/24現在、全然null安全な設計に出来ていません。
Kotlinはコンパイルレベルでnullの扱いを意識させるので
自然に実装完了時点でnull安全な設計が出来るようなコンセプトの言語だと思います。

しかし、僕みたいに即席でだーっと作っちゃうとそこらへんコンパイル通すことだけに集中しちゃったりします。
(多分これはどの言語にも言える事で、実装者やスケジュールなどの問題です)






まず、Groovyが読めないというのが一番の問題でしたw
一方で、gebとGroovyの良い勉強になってるなぁと思います(Kotlinアドベントカレンダーなのに)

あとは、Groovyの表現力をKotlinの表現力にどう置き換えるのか考えるのは楽しいです。


一番困ったのは
1.GroovyのClosureクラス
2.Javaのクラスを使った操作(リフレクション的な)
です。


1.GroovyのClosureクラス



GroovyのClosureはクラスです。
Kotlinで言うところの関数にあたるかなと思います。
厳密には違うのですが、置き換えを考えるとすれば。


GroovyのクロージャとJava8のlambda式の違いについて - uehaj's blog
[Groovy]クロージャのthis、owner、delegateについて - by @saba1024 on @Qiita



List<Closure>とかどうすればいいんや…となりました。
Kotlinでは高階関数が扱えるので引数に関数を渡す事は出来ますが、
Listで型パラメータを指定する必要があるとなると、関数クラス的なものが必要です。
KotilnのFunctionクラスかなんかあった気がするけどpublic interfaceだっけなぁとか。

Higher-Order Functions and Lambdas



2.Javaのクラスを使った操作



gebの内部ではWebDriverインターフェースの具象クラスを切り替えるのにコンフィグを利用しているっぽいです。
そこらへんでjavaのClassLoader使ったりとかしてるわけですが。


Kotlinのクラスの呼び出しとかっていつも思うんですがなんか直感的じゃなくて
忘れちゃうんですよねw

そして、毎回立ち止まって「どうやるんだっけ、これ」ってなって。
単純にコーディング量が少ないからだと思うので精進します!






https://github.com/geb/geb
http://d.hatena.ne.jp/yamap_55/20130330/1364649214
http://waman.hatenablog.com/entry/20120502/1335971122
http://uehaj.hatenablog.com/entry/2015/04/20/025957
http://qiita.com/saba1024/items/b57c412961e1a2779881
http://npnl.hatenablog.jp/entry/20100605/1275736594
http://d.hatena.ne.jp/backpaper0/touch/20110522/1306046873 http://beta.mybetabook.com/showpage/4f27c8cc0cf26106dca875c8
http://qiita.com/nyasba/items/edf102578bde7edf0d4f












gebのクローンライブラリ的なものを作ってみましたが、はからずもGroovyの勉強になりましたw
あと、KotlinとGroovyの比較にもなったかなぁと思います。

実際にKotlinで何かを作るっていうのも一つの目的だったので、
どのぐらい自分がコーディングに時間かけて、どういうところで困るかというのが改めて分かったのも良かったですね。
(ホント個人的なアレですけど)


今の状態だとホント動作すらしないんで話にならないんですが、
洗練されていけばKotlinでE2Eテスト的なものも出来るようになると思います。

gebは良いんですけど、Kotlinからgeb呼び出すのなんかやだなぁとか思いまして。

だったら、素直にspockとgebでやりますよね。



Groovyで出来る事がKotlinで出来ない事は無いですし、実現出来そうな感触はあります。



問題は飽きずに僕がやれるかですねw
GitHubに☆とかつけてくれればちょっと頑張るかもしれません。


ということで、現場からは以上です。お粗末様でした。


え、クリスマス・イヴ?
(∩゚д゚)アーアーキコエナイ







0 件のコメント:

コメントを投稿