Choose checks for a change

Choose checks for a change.

Start with the behavior that could break. A pure helper needs focused input and result checks. A resource write also needs permission and persistence checks. A template change needs a rendered page with representative content.

Compile changed Erlang code before running tests. Run the smallest relevant test first, then checks for affected integrations. Use a disposable database for tests that write data.

Record what was checked and what was not. A successful compile does not verify a browser interaction, and a successful admin request does not verify anonymous access.

Test Erlang behavior with focused examples

Keep domain logic in small functions that accept explicit inputs. Test expected results, boundary values, and meaningful error cases without starting a full site when the function does not need one.

For code that uses Zotonic models, use the repository's existing test setup and a dedicated site context. Clean up created resources so later tests do not depend on execution order.

Select a known test module with the supported test runner. Check that the runner actually discovers it: this workspace's runtests command scans the core apps/zotonic_*/test directories, not every user application's test directory.

For the pure filter example, create test/filter_garden_label_tests.erl in the Garden application:

-module(filter_garden_label_tests).
-include_lib("eunit/include/eunit.hrl").

label_test() ->
    ?assertEqual(<<"Open to visitors">>,
        filter_garden_label:garden_label(<<"open">>, undefined)),
    ?assertEqual(<<"Check visiting times">>,
        filter_garden_label:garden_label(undefined, undefined)).

After building the application, compile this test into a temporary directory and run it with the application's ebin on the path:

mkdir -p /tmp/garden-eunit
erlc -o /tmp/garden-eunit apps_user/zotonic_mod_garden/test/filter_garden_label_tests.erl
erl -noshell -pa _build/default/lib/zotonic_mod_garden/ebin /tmp/garden-eunit -eval 'case eunit:test(filter_garden_label_tests, [verbose]) of ok -> halt(0); _ -> halt(1) end.'

Expect one passing EUnit test. These commands run a pure helper test without a site; use the site's integration test setup for database or permission behaviour.

Check a rendered template

Render the changed page with realistic content. Include missing optional fields, a long title, several list items, and a second language when applicable.

Check links, image descriptions, heading order, and keyboard access. For category-specific markup, test a resource in the exact category and one that uses the fallback template.

Run the template cross-reference check for missing dependencies. Then check the browser console and network responses for scripts or styles that did not load. Save a screenshot when the visual result matters to review.

Run tests and site checks

Use the project's test workflow in a dedicated development or test environment. Two CLI entry points have different scopes:

  • runtests starts the configured test runner and accepts test selections.
  • sitetest garden stops the site, drops and uses the z_sitetest database schema, runs site tests, then restarts with normal configuration. Use a disposable test environment and avoid concurrent runs sharing the database.

Read the relevant reference page before choosing arguments. Tests may create or change data; a passing startup check is not a complete test of models, permissions, and browser behavior.

Run a focused test for the change, then the repository's required broader checks. Preserve the first meaningful error and reproduce it with a minimal case rather than repeatedly restarting the whole node.