作業メモ。
- Elixir 1.0.5
- Phoenix 0.14.0
Plug.Testを使ったやつ
テスト対象
defmodule MyPlug do
import Plug.Conn
def init(options) do
options
end
def call(conn, _opts) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello world")
end
end
テストコード
defmodule MyPlugTest do
use ExUnit.Case, async: true
use Plug.Test
@opts MyPlug.init([])
test "return hello world" do
conn = conn(:get, "/") # コネクションを定義
conn = MyPlug.call(conn, @opts) # コネクションをはる
assert conn.state == :sent
assert conn.status == 200
assert conn.resp_body == "Hello world"
end
end
Phoenixを使ったやつ
test_helper.exs で、test用DBのcreate、migrationを行っているのですね。
test/test_helper.exs
ExUnit.start # Create the database, run migrations, and start the test transaction. Mix.Task.run "ecto.create", ["--quiet"] Mix.Task.run "ecto.migrate", ["--quiet"] Ecto.Adapters.SQL.begin_test_transaction(HelloPhoenix.Repo)
ファイル単位とか、以下のように行単位でテストできるのですね。
$ mix test test/views/error_view_test.exs:12
タグの付与と実行
moduleへのタグ
- moduleへのタグ定義
defmodule HelloPhoenix.ErrorViewTest do use HelloPhoenix.ConnCase, async: true @moduletag :error_view_case
- 実行
$ mix test --only error_view_case
- 実行
$ mix test --only error_view_case:true # 成功する $ mix test --only error_view_case:false # 失敗する。falseを付与したものが存在しないため。
- 特定のタグのみ除いたテストケースの実行
$mix test --exclude error_view_case
test case個別へのタグ
- タグの定義
defmodule HelloPhoenix.ErrorViewTest do
use HelloPhoenix.ConnCase, async: true
@moduletag :error_view_case
import Phoenix.View
@tag individual_test: "yup"
test "renders 404.html" do
assert render_to_string(HelloPhoenix.ErrorView, "404.html", []) ==
"Page not found"
end
@tag individual_test: "nope"
test "render 500.html" do
assert render_to_string(HelloPhoenix.ErrorView, "500.html", []) ==
"Server internal error"
end
- 実行
$ mix test --only individual_test $ mix test --only individual_test:yup # タグをより細かく。 $ mix test --only individual_test: nope # タグをより細かく。
- 特定のmoduleを除いたうえで、
individual_test:yupを実行する
$ mix test --exclude error_view_case --include individual_test:yup
ランダムにテストを実施する
$ mix test --seed 20150712
これ、面白いなーと感じました。 🙂
テストの自動生成
以下のようにcontroller、modelを作成したら、テストケースも自動生成されていました。
作成したモデルに対する、基本的なテストケースの自動生成良いですね。
ざっと生成されたテストケース見てみると、moduleで作成したリソースの生成/更新などの基本的な正常系、作成失敗などのエラー系。
ちなみに、以下を実行した後だと、 phoenix.gen.html とうViewも自動生成されるので、かなりお手軽。
$ mix phoenix.gen.html User users name:string email:string bio:string number_of_pets:integer
test/controllers/user_controller_test.exs
defmodule HelloPhoenix.UserControllerTest do
use HelloPhoenix.ConnCase
alias HelloPhoenix.User
@valid_attrs %{bio: "some content", email: "some content", name: "some content", number_of_pets: 42}
@invalid_attrs %{}
setup do
conn = conn()
{:ok, conn: conn}
end
test "lists all entries on index", %{conn: conn} do
conn = get conn, user_path(conn, :index)
assert html_response(conn, 200) =~ "Listing users"
end
test "renders form for new resources", %{conn: conn} do
conn = get conn, user_path(conn, :new)
assert html_response(conn, 200) =~ "New user"
end
test "creates resource and redirects when data is valid", %{conn: conn} do
conn = post conn, user_path(conn, :create), user: @valid_attrs
assert redirected_to(conn) == user_path(conn, :index)
assert Repo.get_by(User, @valid_attrs)
end
test "does not create resource and renders errors when data is invalid", %{conn: conn} do
conn = post conn, user_path(conn, :create), user: @invalid_attrs
assert html_response(conn, 200) =~ "New user"
end
test "shows chosen resource", %{conn: conn} do
user = Repo.insert! %User{}
conn = get conn, user_path(conn, :show, user)
assert html_response(conn, 200) =~ "Show user"
end
test "renders page not found when id is nonexistent", %{conn: conn} do
assert_raise Ecto.NoResultsError, fn ->
get conn, user_path(conn, :show, -1)
end
end
test "renders form for editing chosen resource", %{conn: conn} do
user = Repo.insert! %User{}
conn = get conn, user_path(conn, :edit, user)
assert html_response(conn, 200) =~ "Edit user"
end
test "updates chosen resource and redirects when data is valid", %{conn: conn} do
user = Repo.insert! %User{}
conn = put conn, user_path(conn, :update, user), user: @valid_attrs
assert redirected_to(conn) == user_path(conn, :index)
assert Repo.get_by(User, @valid_attrs)
end
test "does not update chosen resource and renders errors when data is invalid", %{conn: conn} do
user = Repo.insert! %User{}
conn = put conn, user_path(conn, :update, user), user: @invalid_attrs
assert html_response(conn, 200) =~ "Edit user"
end
test "deletes chosen resource", %{conn: conn} do
user = Repo.insert! %User{}
conn = delete conn, user_path(conn, :delete, user)
assert redirected_to(conn) == user_path(conn, :index)
refute Repo.get(User, user.id)
end
end
test/models/user_test.exs
defmodule HelloPhoenix.UserTest do
use HelloPhoenix.ModelCase
alias HelloPhoenix.User
@valid_attrs %{bio: "some content", email: "some content", name: "some content", number_of_pets: 42}
@invalid_attrs %{}
test "changeset with valid attributes" do
changeset = User.changeset(%User{}, @valid_attrs)
assert changeset.valid?
end
test "changeset with invalid attributes" do
changeset = User.changeset(%User{}, @invalid_attrs)
refute changeset.valid?
end
end
HelloPhoenix.ModelCase は、 test/support/model_case.ex で実装されている。