ElixirでDynamoのsample実行とExUnitを使ってみた
Shinjuku.ex第1回目ということで、新宿 Brooklyn Parlorにて、命の水ビールをぐびぐびしながら、6人ぐらいElixirについてもくもくしてきました。
ちなみに、チュートリアルが2つめなのは、チュートリアルをもくもくするのも良いけれど、動く物を試した用が良いよね!ってことでDynamoを動かそうと、なかなかうまく動くところまでいかなくて、途中で心が折れそうになり、横道反れた結果です。
あと、結論だけ書いてもおもしろくないので、失敗/躓いたところ多めで。
Dynamo を動かしてみる
必要なのは以下の3つ
- erlang
- rebar
- Elixir
erlang / rebar は、macならhomebrewから簡単にインストール出来る
(自分は、rebarがhomebrewにあるとは思ってなかったので、試行錯誤しました)
Elixir のインストールは Getting Started の 1.1.2 Manual install あたりを参照すれば良いかと
http://elixir-lang.org/getting_started/1.html
rebar というのは、erlangにおけるビルドツールらしい。makeやRubyのrakeみたいなもので、rebar.config というファイルにそのタスクが書かれているっぽい
$ git clone https://github.com/josevalim/dynamo.git $ cd ./dynamo $ make setup
make setup で dynamo が依存しているsubmoduleのセットアップとcompileを行う・・・が、普通に失敗する
$ make setup git submodule update --init # 中略 Compiled src/ibrowse_http_client.erl cd deps/cowboy && make make[1]: rebar: No such file or directory # ← ここら辺 make[1]: *** [deps] Error 1 make: *** [setup] Error 2
どうやら、deps/cowboy の make で rebarが無い模様
(homebrew等でインストールしてパスが通っていればこのエラーには遭遇しないはず。たぶん)
rebar がないので、もう一つのsubmoduleで依存しているdeps/ibrowse のrebarを拝借することに
$ cd ./deps/cowboy $ ../ibrowse/rebar get-deps $ ../ibrowse/rebar compile <|| これで cowboy の準備はokで、dynamo の make setup タスクは完了 なお、get-deps / compile はcowboyのMakefileを見ると書いてある 次に dynamo のディレクトリに戻って make compile >|| $ cd ../../ $ make compile
ダメな場合、直接下記を実行してみる
$ elixirc -pa deps/cowboy/ebin lib/*/*/*.ex lib/*/*.ex lib/*.ex -o ebin
これで、 ebin ディレクトリの中にコンパイル済み(?)のファイルが出来ているはず
examples/simple.exs の実行
実行の方法は simple.exs 自体に書かれている
$ cat ./examples/simple.exs [master] # Run this app from root with: # # elixir -pa ebin --no-stop examples/simple.exs defmodule MyApp do # 以下略
$ elixir -pa ebin --no-stop examples/simple.exs Running ::MyApp on port 3000 with Cowboy # この行が表示されれば起動完了
"Running ::MyApp on port 3000 with Cowboy" が表示されない(listenに失敗してる?)場合もあり、どうやら原因不明に失敗している人もいた。
無事に表示された場合、http://localhost:3000/foo/bar にアクセスしてみる (http://localhost:3000/ じゃないよ) と Hello World! が表示されるはず
ExUnit を使ってみる
ExUnitの使い方をいろいろ見てみたいなら、やっぱりリポジトリの /test/ ディレクトリ下を見るのが良いかも
https://github.com/josevalim/dynamo/tree/master/test
基本的には、Rubyなどでもおなじみの /test ディレクトリ下にテストファイルがあり /test/test_helper.exs みたいなのがある感じ
以下、チュートリアルにあったサンプルにテストを追加してみたファイル
例では math.ex として保存して実行してみた
ExUnit.start [] defmodule Math do def sum(a, b) do a + b end end defmodule AssertionTest do use ExUnit::Case def test_pass do assert_equal 30, Math.sum(10, 20) end def test_failed do assert_equal 10, Math.sum(10, 20) end end
$ elixir ./math.ex .F 1) test_failed (::AssertionTest) ** (::ExUnit::AssertionError) Expected 30 to be equal to 10 stacktrace: lib/elixir/builtin.ex:1023: ::Elixir::Builtin.raise/2 lib/ex_unit/assertions.ex:374: ::ExUnit::Assertions.assert/2 lib/ex_unit/runner.ex:78: ::ExUnit::Runner.run_test/3 lib/enum.ex:556: ::Enum.do_each/3 lib/enum.ex:136: ::Enum.each/3 lib/enum.ex:131: ::Enum.each/2 lib/ex_unit/runner.ex:69: ::ExUnit::Runner.run_tests/2 2 tests, 1 failures.
テストケースが2個しかないので表示が寂しいけれど、こんな感じでテストを書くことが出来る
ExUnit でキモになるところは、ExUnit.start [] と書かないと下記のようなエラーになります。
** (exit) "ExUnit::Server is not running. Are you sure you used exunit from command line?" lib/ex_unit/server.ex:59: ::ExUnit::Server.check/1 lib/ex_unit/case.ex:6: ::ExUnit::Case.__using__/2 /Users/toshiwo/var/misc/elixir/math.ex:8: ::ExUnit::Case.__using__/2 src/elixir_dispatch.erl:104: :elixir_dispatch.dispatch_macro/6 lists.erl:1278: :lists.mapfoldl/3 lists.erl:1279: :lists.mapfoldl/3 src/elixir_translator.erl:44: :elixir_translator.translate_each/2 lists.erl:1278: :lists.mapfoldl/3
個人的には ::ExUnit::Server って単語だけで、erlangの message passingなんかを使って、テストケースを並列や分散させて走らせたり出来るのかな〜と妄想全開なところが気になってます
(実際のところの事実はまだ(知らない|調べてない)けれど・・・