Test data with test:given
Task: test a page that depends on data and on who is looking — without a fixtures file and without a password.
The page lists the signed-in user's open tasks:
# Recipe: test data with test:given, and a signed-in user with test:as.
paths:
components: ./components
migrations: ./migrations
datasources:
db:
driver: sqlite
database: ./data/tasks.dbCREATE TABLE tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
owner TEXT NOT NULL,
title TEXT NOT NULL,
done INTEGER NOT NULL DEFAULT 0 CHECK (done IN (0, 1))
);<q:component name="MyTasks" require_auth="true">
<q:query name="mine" datasource="db">
SELECT title FROM tasks WHERE owner = :me AND done = 0 ORDER BY id
<q:param name="me" value="{session.userName}" type="string" />
</q:query>
<h1>{session.userName}'s open tasks</h1>
<q:if condition="mine_result.recordCount == 0">
<p>Nothing to do.</p>
</q:if>
<ul>
<q:loop query="mine"><li>{mine.title}</li></q:loop>
</ul>
</q:component>Each test starts from an empty database built by migrations/. test:given puts in the rows the test needs — through the schema's rules, so a row the app could never have written (a done outside CHECK (… IN …), a missing required column it cannot fill) fails the step instead of slipping in. test:as signs a user in the way a login does:
<q:test name="a user sees only their own open tasks" page="/">
<test:given table="tasks" owner="Ana" title="Write the report" />
<test:given table="tasks" owner="Ana" title="Old task" done="1" />
<test:given table="tasks" owner="Bruno" title="Fix the printer" />
<test:as user="Ana" />
<test:visit />
<test:expect status="200" text="Ana's open tasks" />
<test:expect text="Write the report" />
<test:expect no-text="Old task" />
<test:expect no-text="Fix the printer" />
</q:test>
<q:test name="a user with nothing open is told so" page="/">
<test:given table="tasks" owner="Bruno" title="Fix the printer" />
<test:as user="Ana" />
<test:visit />
<test:expect text="Nothing to do." />
</q:test>
<q:test name="the page needs a signed-in user" page="/">
<test:visit />
<test:expect status="302" />
</q:test>tests/tasks.test.q
PASS a user sees only their own open tasks
PASS a user with nothing open is told so
PASS the page needs a signed-in user
3 passed, 0 failedno-text checks what must not be on the page — here, another user's task and a finished one. The whole vocabulary is in the Testing an App guide.
Tested: this page imports the files of examples/cookbook/testing/test-data/, and the result above is the report of running them.