スポンサーリンク

2015年6月23日

[espec_phoenix]Phoenixでもテストがしたい!!(導入失敗編)

※注意
この記事は最低限の動作確認を取っただけであり未完の記事です。
動作がしなくても保証はしません。一応の証跡として残しておくのみです。


#目的

Elixirのテストフレームワークの一つであるespec_phoenixを利用し、
Phoenixでのテスト環境を整えると同時に基礎的な使い方を習得する。


#実行環境

OS: Windows8.1
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.4
Phoenix Framework: v0.13.1
espec_phoenix: v0.1.3


#始める前に

Phoenixでespec_phoenix(テストフレームワーク)の導入失敗編になります。
(掲題詐欺ですよね・・・この記事・・・orz)

プロジェクトは作成しておいて下さい。
一応、私が実施した作成手順を書いておきます。
----
>cd プロジェクト作成ディレクトリ
>mix phoenix.new espec_phoenix_sample
>選択肢はyes
>cd espec_phoenix_sample
>mix phoenix.server
>ctrl+c
----

以降、プロジェクトまたはアプリケーションと言えば、
作成した名前のものを指すものとします。


#目次

1. インストール
2. セットアップ
3. 初めてのテスト!
4. Phoenixでもテストがしたい!!
5. まとめ


##1. インストール


mix.exsを開き、依存関係に以下の記述を追加して下さい。
----
defp deps do
  ...
  {:espec_phoenix, "~> 0.1.3", only: :test, app: false},
  ...
end
----

次、mix.exsを開き以下の設定を追加して下さい。
----
def project do
  ...
  preferred_cli_env: [espec: :test],
  ...
end
----

mix.exsのソースコード全体はこんな感じになります。
----
defmodule EspecPhoenixSample.Mixfile do
  use Mix.Project

  def project do
    [app: :espec_phoenix_sample,
     version: "0.0.1",
     elixir: "~> 1.0",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix] ++ Mix.compilers,
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps,
     preferred_cli_env: [espec: :test]]
  end

  # Configuration for the OTP application
  #
  # Type `mix help compile.app` for more information
  def application do
    [mod: {EspecPhoenixSample, []},
     applications: [:phoenix, :phoenix_html, :cowboy, :logger,
                    :phoenix_ecto, :postgrex]]
  end

  # Specifies which paths to compile per environment
  defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
  defp elixirc_paths(_),     do: ["lib", "web"]

  # Specifies your project dependencies
  #
  # Type `mix help deps` for examples and options
  defp deps do
    [{:phoenix, "~> 0.13.1"},
     {:phoenix_ecto, "~> 0.4"},
     {:postgrex, ">= 0.0.0"},
     {:phoenix_html, "~> 1.0"},
     {:phoenix_live_reload, "~> 0.4", only: :dev},
     {:cowboy, "~> 1.0"}],
     {:espec_phoenix, "~> 0.1.3", only: :test, app: false}
  end
end
----

依存関係を解決する。
>mix deps.get
>mix deps.compile


##2. セットアップ

以下のコマンドでespecのコマンドがあるか確認してみて下さい。
----
>mix help | grep espec
----

表示されていないと思います。
なので、セットアップにあった内容をWindowsでできるように実施します。
----
>set MIX_ENV=test
>echo %MIX_ENV%
test
>mix help | grep espec
----
何やってるのかさっぱりです・・・

MIX_ENVについて知りたいかは以下をどうぞ。
参考: http://elixir-lang.org/docs/v1.0/mix/Mix.html

続いて以下の二つのコマンドを実施する。
----
>mix espec.init
* creating spec
* creating spec/spec_helper.exs
* creating spec/example_spec.exs

>mix espec_phoenix.init
* creating spec/phoenix_helper.exs
* creating spec/espec_phoenix_extend.ex
* creating spec/controllers
* creating spec/controllers/example_controller_spec.exs
* creating spec/models
* creating spec/models/example_model_spec.exs
* creating spec/requests
* creating spec/requests/example_requests_spec.exs
* creating spec/routers
* creating spec/routers/example_routers_spec.exs
* creating spec/views
* creating spec/views/example_views_spec.exs
----

出力を見た通りですが、
テストをするためのファイルを生成していますね。

spec/spec_helper.exsを開き以下のように編集して下さい。
----
Code.require_file("spec/phoenix_helper.exs")

ESpec.start

ESpec.configure fn(config) ->
  config.before fn ->
    Ecto.Adapters.SQL.restart_test_transaction(EspecPhoenixSample.Repo, [])
    {:ok, hello: :world}
  end

  config.finally fn(__) ->
    __.hello
  end
end
----
EspecPhoenixSample.Repoの部分は自分のプロジェクト名に適宜変換して下さい。

spec/phoenix_helper.exsを開き以下のように編集して下さい。
----
Code.require_file("spec/espec_phoenix_extend.ex")

Mix.Task.run "ecto.create", ["--quiet"]
Mix.Task.run "ecto.migrate", ["--quiet"]
Ecto.Adapters.SQL.begin_test_transaction(EspecPhoenixSample.Repo)
----

これで準備完了です。


##3. 初めてのテスト!

失敗するのもテストの内です。
なので、とりあえず動かしてみましょう!!
----
>mix espec
** (CompileError) spec/requests/example_requests_spec.exs:8: EspecPhoenixSample.Example.__struct__/0 is undefined, cannot expand struct EspecPhoenixSample.Example
    (elixir) src/elixir_map.erl:55: :elixir_map.translate_struct/4
    (stdlib) lists.erl:1352: :lists.mapfoldl/3
----

エラーが出ちゃいましたね・・・
まずはespecが動作することを確認したいですね。


##4. Phoenixでもテストがしたい!!

さて、エラーを消すのはどうするか・・・
動作するだけを確認したいのでexampleのソースコードを削除してしまいます。

以下のソースコードを削除して下さい。
----
spec/example_spec.exs
spec/controllers/example_controller_spec.exs
spec/models/example_model_spec.exs
spec/requests/example_requests_spec.exs
spec/routers/example_routers_spec.exs
spec/views/example_views_spec.exs
----

再度、実行してみましょう。
----
>mix espec
文字化けで読めないがDB関連でエラーが出てる・・・
----

PostgreSQLのエラーログを確認してみた。
何でも、既に存在しているDBを作成しようとしてエラーが出てるみたいです。
とりあえず、既存にあったDBを削除して再度実行します。

----
>mix espec


        [32m0 examples, 0 failures [0m

        [32mFinished in 0.26 seconds (0.25s on load, 0.0s on specs) [0m

>
----

はい動きました。(動作の確認だけですが・・・)

様々な障害を越え、Phoenixとespec_phoenixは両想いに・・・まだなってませんね。
テストを通したわけではないですし・・・


##5. まとめ

最低限の動作はさせられました。

導入途中発生した問題と今後の問題をまとめます


-途中に発生した問題

MIX_ENV=testはRAKE_ENV=testのように動くことになる。
これを知らなかったがために何時間も立ち往生するはめに・・・

ちなみにMIX_ENV=test状態で"mix ecto.create"すると・・・
config/test.exsに書かれているDB名でDBが出来上がる・・・
これが原因で酷い目にあった・・・
知識がないって恐ろしい・・・

ど嵌りしてにっちもさっちもいかなくなって、知り合いのエンジニアにデバッグ頼りました・・・
もしTwitterで「携帯からのElixirとPhoenixとespecのデバックつらい」
とtweetを見かけたらその人です(笑)


-今後の問題

この手のテストを行うフレームワークでは、DBは自動で作成&削除しているものだと思います。(独断と偏見)
なので、DBが自動削除してくれれば問題が解決すると考えている。
環境の問題なのか、設定の問題なのか、DBの問題なのか、フレームワークの問題なのか、
どれなのかは現状では不明。このあたりの調査とLinux環境での実行ではどうなるかの検証が
今後の課題となる。

最初から、Linuxで環境構築すれば良かったんでしょうけど・・・
どうにもLinuxは不慣れでして・・・はぁ

続編: 続!Phoenixでもテストがしたい!!
気力が折れたので気が向いたら作ります。
期待はしないで下さい・・・

追記(2015/07/05)
v0.1.4にバージョンが上がってましたね。
改善されているか期待して試してみたのですが、
mix especするとRuntimeErrorが発生して、
この記事で実施できた部分もできなくなっています。

かと言ってmix.exsでv0.1.3を指定しても
何故か最新版を取得してしまうので、
バージョンを戻すこともできなかったです。
(mixに対しての知識不足?)

まぁ、安定するバージョンが出るまで大人しく待つとしましょう。
ESpecの方は実行できるようになったので・・・
ESpecの参考記事: [Elixir]ElixirでもBDDがしたい!!


#参考文献

Elixir |> BDD
https://github.com/antonmi/espec_phoenix
http://elixir-lang.org/docs/v1.0/mix/Mix.html

人気の投稿