Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Concurrent Feature tests with Wallaby

Concurrent Feature tests with Wallaby

Chris Keathley

September 05, 2016
Tweet

More Decks by Chris Keathley

Other Decks in Programming

Transcript

  1. Feature Tests Represent real users Provide Confidence in the System

    (Sometimes) (When they aren’t randomly failing)
  2. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") end end
  3. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") end end
  4. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") end end
  5. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") end end
  6. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text end end
  7. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end
  8. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end
  9. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end
  10. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end
  11. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end Sessions Queries actions
  12. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end Sessions Queries actions
  13. setup tags do {:ok, session} = Wallaby.start_session([]) on_exit, fn ->

    Wallaby.end_session(session) end {:ok, session: session} end
  14. setup tags do {:ok, session} = Wallaby.start_session([]) on_exit, fn ->

    Wallaby.end_session(session) end {:ok, session: session} end
  15. setup tags do :ok = Ecto.Adapters.SQL.Sandbox.checkout(YourApp.Repo) metadata = Phoenix.Ecto.SQL.Sandbox.metadata_for( YourApp.Repo,

    self()) {:ok, session} = Wallaby.start_session(metadata: metadata) on_exit, fn -> Wallaby.end_session(session) end {:ok, session: session} end
  16. setup tags do :ok = Ecto.Adapters.SQL.Sandbox.checkout(YourApp.Repo) metadata = Phoenix.Ecto.SQL.Sandbox.metadata_for( YourApp.Repo,

    self()) {:ok, session} = Wallaby.start_session(metadata: metadata) on_exit, fn -> Wallaby.end_session(session) end {:ok, session: session} end
  17. setup tags do :ok = Ecto.Adapters.SQL.Sandbox.checkout(YourApp.Repo) metadata = Phoenix.Ecto.SQL.Sandbox.metadata_for( YourApp.Repo,

    self()) {:ok, session} = Wallaby.start_session(metadata: metadata) on_exit, fn -> Wallaby.end_session(session) end {:ok, session: session} end
  18. setup tags do :ok = Ecto.Adapters.SQL.Sandbox.checkout(YourApp.Repo) metadata = Phoenix.Ecto.SQL.Sandbox.metadata_for( YourApp.Repo,

    self()) {:ok, session} = Wallaby.start_session(metadata: metadata) on_exit, fn -> Wallaby.end_session(session) end {:ok, session: session} end
  19. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end Sessions Queries actions
  20. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end Sessions Queries actions
  21. Thanks for signing up! <div class="alert"> <span class=“msg"> Thanks for

    signing up! </span> </div> session |> find(“.alert")
  22. Thanks for signing up! <div class="alert"> <span class=“msg"> Thanks for

    signing up! </span> </div> session |> find(“.alert")
  23. <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span

    class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div> HTML
  24. <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span

    class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div> HTML Test - User Names session
  25. <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span

    class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div> HTML Test - User Names session |> find(".user")
  26. <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span

    class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div> HTML Test - User Names session |> find(".user") Ambiguous
  27. <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span

    class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div> HTML Test - User Names session |> find(".user", count: 2)
  28. <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span

    class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div> HTML Test - User Names session |> find(".user", count: 2) |> Enum.map(& find(&1, ".name") )
  29. <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span

    class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div> HTML Test - User Names session |> find(".user", count: 2) |> Enum.map(& find(&1, ".name") ) |> Enum.map(& text(&1) ) # => ["Grace Hopper", "Alan Turing"]
  30. session HTML Test - Grace’s Email <div class="users"> <div class="user">

    <span class=“name"> Grace Hopper </span> <span class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div>
  31. session |> find(".user", text: "Grace Hopper") HTML Test - Grace’s

    Email <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div>
  32. session |> find(".user", text: "Grace Hopper") |> find(".email") HTML Test

    - Grace’s Email <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div>
  33. session |> find(".user", text: "Grace Hopper") |> find(".email") |> text

    # => "[email protected]" HTML Test - Grace’s Email <div class="users"> <div class="user"> <span class=“name"> Grace Hopper </span> <span class=“email"> [email protected] </span> </div> <div class="user"> <span class=“name"> Alan Turing </span> <span class=“email"> [email protected] </span> </div> </div>
  34. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end Sessions Queries actions
  35. defmodule YourApp.UserRegistrationTest do use YourApp.AcceptanceCase, async: true test "users can

    register", %{session: session} do session |> visit("/users/new") |> find(".registration_form") |> fill_in("Full Name", with: "Grace Hopper") |> fill_in("Email", with: "[email protected]") |> fill_in("Password", with: "password") |> click("Register") msg_text = session |> find(".flash-message") |> text assert msg_text == "Welcome Grace Hopper" end end Sessions Queries actions
  36. <form> <label for=“user_name"> Name </label> <input type="text" name=“user_name"> <button type=“submit">

    Register </button> </form> HTML Test session |> fill_in("Name", with: "Grace Hopper")
  37. <form> <label for=“user_name"> Name </label> <input type="text" name=“user_name"> <button type=“submit">

    Register </button> </form> HTML Test session |> fill_in("Name", with: "Grace Hopper") |> click_on("Register")
  38. HTML Test session |> fill_in(“user_name", with: "Grace Hopper") |> click_on("Register")

    <form> <label for=“user_name"> Name </label> <input type="text" name=“user_name"> <button type=“submit"> Register </button> </form>
  39. HTML Test session |> fill_in(“user_name", with: "Grace Hopper") |> click_on("Register")

    <form> <label for="user_name"> Name </label> <input type="text" name=“user_name"> <label> <input type="checkbox" value="true" name="save_login"> Save login </label> <button type="submit"> Register </button> </form>
  40. HTML Test session |> fill_in(“user_name", with: "Grace Hopper”) |> check("Save

    login") |> click_on("Register") <form> <label for="user_name"> Name </label> <input type="text" name=“user_name"> <label> <input type="checkbox" value="true" name="save_login"> Save login </label> <button type="submit"> Register </button> </form>
  41. fill_in(session, "First Name", with: "Chris") choose(session, "Radio Button 1") check(session,

    "Checkbox") uncheck(session, "Checkbox") select(session, "My Awesome Select", option: "Option 1") click_on(session, "Some Button") attach_file(session, "File", path: "path/to/file") Other Actions