最近テストについて勉強したいなぁと思っていたので調べてみた。
この記事は、主にelm-testとelm-checkの周辺?の話になる。
わからなかったところも多いので、また考えたい。
いろいろ試してみた的なgithubレポジトリ。
#Elmのテストライブラリ
Elmでテストするときは以下のライブラリを使う。
-
elm-test
- assertテスト用のライブラリ。
- コンソールで結果を確認も出来る。ドキュメントにはTravisCIで動かす例なんかも載っている。
-
elm-check
- プロパティベーステストを行うライブラリ。
- プロパティ(性質)ベーステストとは、主張、反証といった方向から行うテスト、よくわかってない。純粋なコードに使っていくようだ(http://d.hatena.ne.jp/kazu-yamamoto/20121205/1354692144)。
- またランダムな値でelm-testを自動生成することも出来る。
- 結果をelm-testのTest型にすることもできる。
#テストの確認方法
テストの出力形式について。
html(またはjs)ファイルと、コンソール確認する方法がある。
##.html または .js
main : Element
main =
elementRunner tests --elementRunnerやstringRunnerで、ElementやHtmlに出来る。
コンパイルしてできたhtmlをブラウザで開くと、テスト結果を確認できる。Elmらしい
出来たhtmlを、jsテストランナーから確認する技もある。後述
##コンソールで確認する
elm-testはelm-console(旧elm-io)をサポートしている。(consoleRunnerという、IO () 型にできる関数がある。)
elm-consoleは、nodeで実行出来るようにするライブラリ。
流れとしては、まずportに対して、IO () をConsole.runする。
port runner : Signal (Task.Task x ())
port runner =
Console.run (consoleRunner tests)
次にそのelmファイルを、一旦jsファイルとして出力する。
elm-make ./Main.elm --output ./raw-test.js
次に、ダウンロードしたelm-stuff内にある、elm-consoleフォルダ内にあるelm-io.shファイルをbashで起動して使う。引数に先ほどのjsファイルと、最終的な名前を入れる。bashスクリプトがやっていることは、workerモードでElm.Mainを起動するコードを付け足している。
bash プロジェクトパス/elm-stuff/packages/laszlopandy/elm-console/1.0.3/elm-io.sh ./raw-test.js ./test.js
そしてそのファイルをnodeで起動すると、テスト結果をコンソールで確認できる。
node ./test.js
###elm-checkの確認方法
elm-checkの方についての話題。elm-checkの基本的な型をHtmlで確認する関数は、今のバージョンでは何故かないようだ。だがこちらのブログ([Running Elm Check with phantomjs]
(http://zkessin.github.io/elm-examples-blog//testing/phantomjs/elm-check/2015/12/21/phantomjs-and-elmcheck.html)
)に書かれたコードで、elm-testのTest型に変換できる。
つまりelm-checkはすべてelm-testのTest型にして確認すればいいと思われる。
##どっちを使うか
出力がhtmlと、コンソールがあるのを確認したが、どっちをどうつかうのか。
個人的にはElmを書くときは、elmファイルとelmテストファイルをwatchして、テスト結果はコンソール確認しながら書く。
Elmから離れて大きな集合(htmlファイル+jsファイル全体で行いたいことや、クリックしたら結果どう表示が変わる等)でテストをしたいときは、jsでテストファイルを書いて、elmのテストは(できればhtml)で吐いて、それをjsテストから確認して、最終的にjsテストの結果一本を見る。とかできたら良いな。(まだよくわからない)
Elmのテストライブラリを使ってこういう方法があるんだなという話
elm-web-api
というプロジェクトが、複数ブラウザでテストしたり、すべてTask型でテストコード書いたりと、いろいろやってて参考になる。
##elm-testのテスト結果を他のテストランナーから確認する。
elm-web-apiだとこことこの部分。
elmのテスト結果の文字列をdomからとりだして、failを数えている。
以下のブログではファントムjsでとっている。
[Running Elm Check with phantomjs]
(http://zkessin.github.io/elm-examples-blog//testing/phantomjs/elm-check/2015/12/21/phantomjs-and-elmcheck.html)
##テストをすべてTask型でかく書き方。
- Nativeを呼び出すElmのコード
- Signal型
なんかにはTask型でシーケンスに書けて有効っぽい。
参考
elm-signal-extraのテスト
sampleというSignalをTask型にする関数を定義してテストしたりしている。
こんな書き方もあるんだなぁと。
##jsdomでdomのテスト。
domのテストをjsdomを使うと、ブラウザの類を立ち上げる必要なくできると聞いたので、冒頭あげたレポジトリ内でちょっと試してみてる。
でもjsdomの使い方と、テストでの使い方でつまずいてdom内の文字の確認するしかできなかった。。
var fs = require('fs');
var elmApp = fs.readFileSync("dist/client/app/elm.js", "utf-8")
var mainJs = fs.readFileSync("dist/client/main/main.js", "utf-8")
describe('domのテスト', () => {
var result, button, $;
jsdom({
file: "dist/client/index.html",
src: [elmApp, mainJs],
skipWindowCheck: true
});
before(function() {
result = document.querySelector("#result");
button = document.querySelector("#testButton");
$ = rerequire('jquery');
});
describe('dom表示のテスト', function() {
it('結果を表示と出る', function() {
assert(result.textContent === "結果を表示")
});
it('押したあと、error!と表示', function(done) {
$("#testButton")
.click();
setTimeout(function() {
result = document.querySelector("#result");
assert(result.textContent == "error!");
done()
}, 500);
});
});
});
reactではクリックのシュミレート用の関数とかあって、いい感じっぽいんですが、elmじゃ聞かないしまだ早いかもしれない。まずヘッドレスブラウザ等で考えるべきだったかも。
#まとめ
Elmのテストライブラリと出力方法を確認してみた。そして新たな書き方や、Html出力したものを他のテストツールから確認したりする方法を知った。
elm-web-apiを見てたら、mocha(等テストランナー)からみたらelmもただのいちjsファイルって感じに出来そうなのが個人的に良い。
httpを使ったコードとか、taskとか、jsのテストツール群とか、テストはいくらでも深くできそうなので、またその都度調べていきたい。
今年はElmを追っててとても楽しく、勉強になった、来年もやるぞい。