Jeffrey Hicks

Jeffrey Hicks

Platform Eng @R360

18 - Phoenix crash course #18: Testing contexts and controllers

Learn how to write effective tests for Phoenix contexts and controllers using ExUnit

By Daniel Bergholz • Aug 19, 2025

Learn how to write effective tests for Phoenix contexts and controllers using ExUnit.

Running and targeting tests

  • Use mix test to run all tests, or pass a folder/file (e.g., mix test test/shop/) to target specific groups
  • You can run a single test by specifying the line number: mix test test/shop/promotions_test.exs:13

Test folder structure

  • Mirrors lib/ structure: test/shop/ for contexts, test/shop_web/ for controllers and web layer
  • test/support/fixtures/ contains helper code and fixtures for test data

Test helpers

  • ConnCase: sets up the connection and helpers for testing controllers
  • DataCase: sets up data and helpers for testing contexts/modules that interact with Ecto
  • Use async: true in tests for parallel execution, but only if your DB supports it (Postgres yes, SQLite no)

Writing tests for contexts

  • Use fixtures to quickly insert required data (e.g., generating products or promotions)
  • Test context functions like list_products, create_product, by calling them directly and asserting on results

Writing controller tests

  • Use ConnCase, which provides a fake connection (conn) for requests
  • Use functions like get(conn, "/products") and assert html_response(conn, 200) =~ "expected text"
  • Qualify/check for response codes, page contents, etc.
  • Use fixtures to seed the database as needed before controller actions

Fixing failing tests

  • If you update your views/pages, make sure tests look for the correct text/html structure

Tips

  • Atom or integer fields in test assertions may need to be converted to strings with to_string/1 in assertions against HTML response text
  • For LiveView tests (coming later), use live/2 instead of get/2

Summary

Phoenix’s testing suite is flexible and idiomatic, comes with helpers for context (data) and controller (web) tests, supports fixtures and async by default, and encourages structure and clear assertions for robust, maintainable test coverage of your web app’s backend and frontend layers.

Related

#phoenix-and-elixir #phoenix-crash-course #daniel-bergholz