2017-01-03 4 views
1

Exunitはセットアップブロックhttps://hexdocs.pm/ex_unit/ExUnit.Callbacks.htmlのコールバックを提供しているようです。私はそれがwallaby機能テストでどのようにできるのか不思議です。私は基本的に、統合テストをテストする際には、すべてのシナリオでユーザーを作成します。私は基本的に定型コードを取り出して、私が書いたすべてのテストに使用したいと思っています。ここでは、統合テストのための私の現在の設定です。エリキシルのテストへの設定の追加

test "a user can create a location", %{session: session} do 
    assert session 
     |> visit("/users") 
     |> click_link("Create new account") 
     |> fill_in("Name", with: "Billy Joel") 
     |> fill_in("Email", with: "[email protected]") 
     |> fill_in("Password", with: "password") 
     |> click_on("Create new user") 
     |> click_link("New Project") 
     |> fill_in("Name", with: "Senior Class Air Quality") 
     |> click_on("Submit") 
     |> click_link("Senior Class Air Quality") 
     |> click_link("New Location") 
     |> click_on("Submit") 
     |> find(".alert-danger p") 
     |> text == "Oops, something went wrong! Please check the errors below." 

    assert session 
     |> fill_in("Name", with: "A new location") 
     |> select("Type", option: "office") 
     |> click_on("Submit") 
     |> find(".alert-info") 
     |> text == "Location created successfully." 

    assert session 
     |> find("td", count: 3) 
     |> List.first 
     |> text == "A new location" 
    end 

    test "a user can edit a location", %{session: session} do 
    project = Factory.project() 
    Factory.location(%{project_id: project.id}) 

    assert session 
     |> visit("/users") 
     |> click_link("Create new account") 
     |> fill_in("Name", with: "Billy Joel") 
     |> fill_in("Email", with: "[email protected]") 
     |> fill_in("Password", with: "password") 
     |> click_on("Create new user") 
     |> click_link("New Project") 
     |> fill_in("Name", with: "Senior Class Air Quality") 
     |> click_on("Submit") 
     |> click_link("Senior Class Air Quality") 
     |> click_link("New Location") 
     |> fill_in("Name", with: "A new location") 
     |> select("Type", option: "office") 
     |> click_on("Submit") 
     |> click_link("Edit location") 
     |> fill_in("Name", with: "different name") 
     |> select("Type", option: "home") 
     |> click_on("Submit") 
     |> find(".alert-info") 
     |> text == "Location updated successfully." 

そこには重複が多数あります。セットアップブロックを使用してこのコードの一部を統合するにはどうすればよいですか?

答えて

1

setupsetup_allの機能は、モジュール内のすべてのテストに対してまったく同じ設定コードを実行します。これらの機能は、まったく同じ設定をすべて実行する必要がある場合に最も便利です。これの一例は、あなたのアプリケーションが依存する模擬サービスを設定することです。

あなたのケースでは、同じ手順がいくつかあるようですが、さらにテストを追加すると、必ずしもすべての設定が共通するわけではありません。

defmodule TestHelpers do 
    # wallaby imports here 

    def create_user(session, name, email, password) do 
    session 
     |> visit("/users") 
     |> click_link("Create new account") 
     |> fill_in("Name", with: name) 
     |> fill_in("Email", with: email) 
     |> fill_in("Password", with: password) 
     |> click_on("Create new user") 
    end 

    def create_project(session, name) do 
    session 
     |> click_link("New Project") 
     |> fill_in("Name", with: name) 
     |> click_on("Submit") 
    end 

    def create_location(session, type), do: _modify_location("New Location", session, type, name) 

    def edit_location(session, type), do: _modify_location("Edit location", session, type, name) 

    defp _modify_location(link_text, session, location_type, location_name) do 
    session = session 
     |> click_link(link_text) 

    session = case location_name do 
     nil -> session 
     x when is_binary(x) -> fill_in(session, "Name", with: location_name) 
    end 

    session = case location_type do 
     nil -> session 
     x when is_binary(x) -> select(session, "Type", option: location_type) 
    end 

    session 
     |> click_on("Submit") 
    end 
end 

今すぐテストが唯一TestHelpersで定義されたヘルパーとアサーションで構成されています。ただし、すべての統合テストに使用したいテストは別のモジュールに構成されている個々の概念の手順をリファクタリングすることができます:

defmodule Test do 
    import TestHelpers 

    @project_name "Senior Class Air Quality" 

    # aliases, uses, imports here 
    test "a user can create a location", %{session: session} do 
    session = session 
     |> create_user("Billy Joel", "[email protected]", "password") 
     |> create_project(@project_name) 
     |> click_link(@project_name) 
     |> create_location(nil, nil) 

    assert session 
     |> find(".alert-danger p") 
     |> text == "Oops, something went wrong! Please check the errors below." 

    session = session 
     |> create_location("A new location", "office") 

    assert session 
     |> find(".alert-info") 
     |> text == "Location created successfully." 

    assert session 
     |> find("td", count: 3) 
     |> List.first 
     |> text == "A new location" 
    end 

    test "a user can edit a location", %{session: session} do 
    project = Factory.project() 
    Factory.location(%{project_id: project.id}) 

    session = session 
     |> create_user("Billy Joel", "[email protected]", "password") 
     |> create_project(@project_name) 
     |> click_link(@project_name) 
     |> create_location("office", "A new location") 
     |> modify_location("home", "different_name") 

    assert session 
     |> find(".alert-info") 
     |> text == "Location updated successfully." 
    end 
end 

あなたも同様に非常に読みやすく、堅牢なテストのそれぞれを作るべき、ワンライナーにそれらを有効にする警告メッセージのアサーションを抽出することができれば、例えば、リンクテキストまたはdivクラスの変更 - あなたはヘルパーに変更を加えるだけです。

もちろん

あなた自身がテストで繰り返しマルチステップの設定を持つ見つけた場合、あなたはヘルパー関数としてそれを持っているし、それを直接使用することができます。

def standard_setup(session) do 
    session 
    |> create_user("Billy Joel", "[email protected]", "password" 
    |> create_project(@project_name) 
    |> click_link(@project_name) 
    |> create_location("office", "A new location") 
end 
関連する問題