# Phoenix > Test _smarter_, not harder ------ ### The Evolution of a ## Feature test --- ## Test pyramid
ยข
$$$
- e2e - acceptance - feature - integration - unit
https://martinfowler.com/bliki/TestPyramid.html
--- ##
Phoenix
- wallaby / playwright ๐ง - phoenix_test - LiveViewTest - ConnTest
--- ## Playwright
https://www.bigbinary.com/blog/why-we-switched-from-cypress-to-playwright
--- ## Wallaby
- chromedriver - selenium - HTTP + JSON: WebDriver Wire Protocol - chromedriver: CDP
- https://w3c.github.io/webdriver/ - https://www.edureka.co/blog/selenium-webdriver-architecture/
--- ## ๐ Ruby on Rails ```rb require "application_system_test_case" class RegistrationTest < ApplicationSystemTestCase test "register" do visit registration_path fill_in "Email", with: "f@ftes.de" fill_in "Password", with: "1234" click_on "Register" assert_text "Account created" ```
- rack_test - selenium - cuprite
https://www.allthingswild.co.uk/wild-bunch/capybara-2/
--- ## phoenix_test Made with โค๏ธ by German Velasco ```ex test "register", %{conn: conn} do conn |> visit("/register") |> fill_in("Email", with: "f@ftes.de") |> fill_in("Password", with: "1234") |> submit() |> assert_has("#flash-info", text: "User created") ```
- static - live - playwright ๐ง
https://www.germanvelasco.com/blog/introducing-phoenix-test (Jan 31, 2024)
--- ## Demo time # ๐ฟ --- ```sh [1|3-4|6|8] mix phx.gen.auth Accounts User users Do you want to create a LiveView based authentication system? [Yn] n mix test ```
--- ```ex [1|6-8|11|14-16] defmodule SmartWeb.UserRegistrationControllerTest do test "creates account and logs the user in", %{conn: conn} do email = unique_user_email() conn = post(conn, ~p"/users/register", %{ "user" => valid_user_attributes(email: email) }) assert get_session(conn, :user_token) assert redirected_to(conn) == ~p"/" # Now do a logged in request and assert on the menu conn = get(conn, ~p"/") response = html_response(conn, 200) assert response =~ email assert response =~ ~p"/users/settings" assert response =~ ~p"/users/log_out" ``` --- ```ex [1|10-12|13-14|15] defmodule UserRegistrationTest do use Smart.DataCase use PhoenixTest.Case test "register, log out and in", %{conn: conn} do conn |> visit("/") # Register |> click_link("Register") |> fill_in("Email", with: "f@ftes.de") |> fill_in("Password", with: "password1234") |> submit() |> assert_has("#flash-info", text: "User created") |> open_browser() # Log out # Log in ``` --- ```sh [1|3-4|6|8] mix phx.gen.auth Accounts User users Do you want to create a LiveView based authentication system? [Yn] y mix test test/features/user_registration_test.exs ```
```html [1-2|4|6-9] Could not find any elements with selector "#flash-info" and text "User created" Found these elements matching the selector "#flash-info":
Success! Account created successfully!
```
--- ```ex [14-15|13|11] defmodule UserRegistrationTest do use Smart.DataCase use PhoenixTest.Case test "register, log out and in", %{conn: conn} do conn |> visit("/") # Register |> click_link("Register") |> fill_in("Email", with: "f@ftes.de") |> fill_in("Password", with: "password1234") |> submit() # |> assert_has("#flash-info", text: "User created") |> assert_has("#flash-info", text: "Account created") # Log out # Log in ``` --- ```ex [5|6] conn |> visit("/") |> click_link("Register") |> fill_in("Password", with: "short") |> assert_has(".text-rose-600", text: "at least 12") ```
--- ```heex [5|11|12-13] <.simple_form for={@form} id="registration_form" phx-submit="save" phx-change={false # "validate"} phx-trigger-action={@trigger_submit} action={~p"/users/log_in?_action=registered"} method="post" > <.input field={@form[:email]} type="email" label="Email" required /> <.input phx-hook="Password" field={@form[:password]} type="password" label="Password" required />
should be at least 12 character(s)
```
```sh mix phx.server ```
--- ```sh [1|2] mix test test/features/user_registration_test.exs 1 test, 0 failures ```
```ex [8] conn |> visit("/") |> click_link("Register") |> fill_in("Email", with: "f@ftes.de") |> fill_in("Password", with: "short") # |> assert_has(".text-rose-600", text: "at least 12") |> assert_has(".text-rose-600:not(.hidden)", text: "at least 12") ```
```sh [2] mix test test/features/user_registration_test.exs 1 test, 1 failure ```
--- ```ex [3-6|8] defmodule UserRegistrationTest do use Smart.DataCase use PhoenixTest.Case, playwright: :chromium, headless: false, slow_mo: 900 @tag :playwright test "register, log out and in", %{conn: conn} do conn |> visit("/") |> fill_in("Password", with: "short") |> assert_has(".text-rose-600:not(.hidden)", text: "at least 12") ```
```sh [2] mix test test/features/user_registration_test.exs 1 test, 0 failures ```
--- ## ๐ Summary - feature tests = phoenix_test - Don't lose it - reuse it ๐ถ - โ static + live view (vanilla) - ๐ง playwright (JS) - ๐ง advanced assertions (locators, input values) --- ### Fredrik Teschke Freelance Dev `f@ftes.de` `@ftes` ---
#### co-founder of ## BogenGaudi #### Arrow Tag rental by ๐ฆ
---
### `teamengine.co.uk` ------ > Digital contracting & time-recording\ > for the Film & TV industry --- ## ๐ญ Other stuff ๐ฌ - graphite - mix_unused - a11y_audit_elixir - test_also_with