How-to
Run a test
Updated
On this page
Run one or more tests against your app whenever you like: smoke, latency, accessibility, transport security, API contract and end-to-end tests, a compliance scan, your repository's own unit tests, or, once your address is verified, load, stress, scalability, endurance and SQL injection tests.
Setting up a run takes about 2 minutes. A manual or scheduled run is for testing only: it never authorizes a release. Pull request runs feed their pull request's decision on Releases.
Before you start
You need a repository connected to Zof and, for every test except unit tests, a public https address where your app runs, such as https://www.example.com. Zof only tests that address.
Start a run
Choose Run tests in the top bar, or New run on Runs. The wizard has 5 steps, and you can pick several tests for one run.
Select App & Env. Choose the Repository. The wizard opens on the repository in the link, else the one you last chose in it, else the project picked in the header, so starting over keeps your choice. With several repositories connected and none of those, none is selected until you pick one. If your company hasn't connected GitHub yet, the step says so with Connect GitHub, which opens the connect dialog, and Continue says "Connect GitHub to choose a repository." Pick the Environment from your company's environments, the same list as the header (production isn't listed: it is never a run target). It's optional: only tests that count in certain environments use it. If you skip it, or a test doesn't count in the one you picked, Options asks once which of your environments the address is. Zof never guesses. Leave Branch empty to test the latest commit on the default branch, or pick or type a branch to test its tip. Type the start of a name to find it (capitals count). The hint says when the list isn't every branch. Type any other and Zof checks it. The wizard names the commit, for example "Tests run against commit 1a2b3c4 (latest on main)."
Run Type. Choose Manual to run now, Pull Request to test an open pull request's head commit, or Scheduled to create a schedule. For a pull request, pick it from the repository's open pull requests, choose Load more pull requests to reach older ones, or enter its number or paste its GitHub URL, which also works when the list can't load, unless the pull request is too far down the company's open list to look up. A URL must be for the repository you chose. The wizard names that commit, for example "Tests run against commit 1a2b3c4 (head of PR #12)." If Zof can't read the pull request's head commit, the run doesn't start: Zof never tests the default branch in its place. A pull request run is for testing only: the pull request's own Zof check decides its gate (see Releases).
Test types. Tick one or more tests, grouped by category, up to 12 in one run. At 12 the other tests can't be ticked until you untick one. Select all ticks the tests that can run now, quick checks first, stops at 12, and says what it left out. A schedule has no limit, and Select all leaves out what can't be scheduled. Load, stress, scalability and endurance tests, SQL injection scans and payment idempotency tests send heavy or probing traffic. Address proof for them is turned off for now, so they run on any address you enter, with no Proof needed tag and no tick, and Select all ticks them too. Schedules still can't run them. Zof will turn address proof back on; then they're marked Proof needed again, Zof reads the proof in Options, where you also tick I'm authorized to test, and the first Select all leaves them out. See Verify your address. Every test type the engine has a configured, healthy agent for is listed. A type you can't tick here carries one tag: Advisory (results only; it opens its own run on the repository you chose; API fuzzing opens here) or Not available (hover for why). While Zof checks, it says Checking…; if it can't check, it offers Retry, and never shows the type as available. See What each test checks.
Options. Enter what your tests need:
- Where it runs: Your site, the public address of your web app, and Your API for tests that call your API. Both offer the addresses saved for this repository or seen deployed from it, each with where it came from, and you can type any other. A saved address fills an empty field and says it's saved; a deployed address goes in only when you pick it. Zof tests a root address, so a full URL such as
https://you.github.io/project/gets a button that useshttps://you.github.iowith the page/project/. Tick My API is on the same address as my site if it is. Unit tests run in Zof's sandbox at the commit and need no address. - What to test: Pages, one path per row, such as
/pricing, up to 10 (/by default). Add, paste, reorder (arrows or Alt+Up/Down) and remove rows; a row that isn't a path on your address says why, often with a fix. The broken-link crawl starts at each page. Choose Customize per test to give each test its own pages, or Find pages to list your address's pages, key pages first, and add the ones you tick after your own. Find pages opens the site address saved for the repository, or an address deployed from it. On a GitHub project site, choose Add with the folder first, so it looks under that folder. API contract tests take API endpoints, end-to-end tests take User journeys, the compliance scan takes a Compliance standard, load and endurance tests take Users at once, Minutes and acceptance limits, and the SQL injection scan takes Addresses to probe. Stress takes a Stress profile with baseline, peak and recovery settings; scalability takes increasing Concurrent user steps and Seconds per step. Both send GET requests to one path on a staging or performance address. - Run note (optional): why you started the run. It's kept with the run and shown on its page. Scheduled runs don't keep one.
- Prove the address: only while address proof is on (it's off for now, so this section doesn't show). For a test marked Proof needed, each address shows Proven ✓ or Not yet. Open Prove the address, then run it to verify it, and tick I'm authorized to test the address.
Each test saves what its agent records; there's nothing to switch on. Choose Review run.
- Where it runs: Your site, the public address of your web app, and Your API for tests that call your API. Both offer the addresses saved for this repository or seen deployed from it, each with where it came from, and you can type any other. A saved address fills an empty field and says it's saved; a deployed address goes in only when you pick it. Zof tests a root address, so a full URL such as
Review. Check the summary, how long it takes and the credits it holds: 1.5 credits for each test that reaches a result, so 3 tests hold up to 4.5 credits. A test with no result uses nothing. On your company's own AI key the hold is the same, with "less on your own key": each test that runs on the key is charged 60% less. If Zof can't check the cost, the review says so instead of showing a number. Each test shows Runs now or Waiting for proof. Choose Create run. For a scheduled run, enter a Name, when it Repeats (hourly, daily, weekdays, weekly or monthly), the time and the Time zone, then choose "Create 2 schedules". Advanced (cron) edits it as cron. Pick Manual only under Repeats for a schedule that runs only when someone chooses Run Now.
The box "This address serves commit 1a2b3c4" starts unticked, for your site and your API. Tick it only if that address runs this commit. Zof doesn't check your tick: evidence files you download from new runs that relied on it say "Commit declared, not verified". Unticked, Zof refuses the tests unless it serves that commit itself. Until Zof knows the commit, the box says "Checking the latest commit…" and can't be ticked. If Zof doesn't answer, the wizard tries again once by itself, then says so with Retry.
If the address you entered isn't the repository's saved address, the wizard says "This repo's saved address is …". Choose Use saved address, or, if you're a company admin, Replace saved address.
Saved test sign-in
When saved test sign-in is on, supported manual website tests can sign in with one saved test account. In Options, when a test you picked can use a signed-in session, Zof asks for the Test account email and Test account password under Your site, with the page that proves sign-in worked. For another test, tick This site needs sign-in to ask for them. Leave them empty to run public checks. Choose Signed-in checks for supported tests. A test you picked that can't use the saved sign-in, such as the compliance scan, doesn't block the run: it runs as public checks, Options says so, and the review and the run's page label it Public checks (ran signed-out). A test that can sign in never falls back: a failed or unavailable sign-in never starts a public test instead. Scheduled and pull request runs cannot use this account automatically, and website sign-in does not authenticate API calls.
Beside the email and password, enter the Protected page (only visible when signed in): a path on your site that a signed-out visitor can't see, such as /dashboard. It has no default. Zof signs in, then opens that page to prove sign-in worked; a landing URL alone does not prove it. Also add Text shown only when signed in (recommended): words on that page that a signed-out visitor never sees, such as "Sign out". Until the protected page is a path other than the login path, Save and use this account stays unavailable and says why. Under Advanced, the Login path is /login by default.
Keep Save this test account ticked and choose Save and use this account. Zof saves the account to your repository's application, adding the repository as an application if it isn't one yet, and selects it for this run. The password is write-only: it's encrypted, never shown again, and a run carries only the account's version. Zof signs in only with a saved account, so with Save this test account unticked the run can't sign in. Entering, changing or removing an account requires permission to edit tests; without it you can use a saved account but not enter one. This supports one ordinary username/password form on the exact website address; OAuth, SSO, MFA and CAPTCHA are unsupported.
If your site signs in through a hosted sign-in service on another address, add that address under Advanced as the Sign-in service address, such as https://xyz.supabase.co: up to 3, one per line, each a host with no path. xyz.supabase.co alone works too: Zof adds the https://. Zof's browser may then call that address while it signs in and while it's signed in, but never opens it as a page, so your test password is also sent to it. The saved account then says "Your test password is also sent to:" and names each one. Adding or changing a sign-in service address needs permission to configure the company. Sign-in that sends the browser to another page or provider (redirect sign-in) isn't supported.
Next time, Options shows the account as "Saved account: d•••@example.com", only its first character and domain, with Use this account for this run ticked. Choose Change to replace it: the protected page, its text and any sign-in service address are kept, and you enter the email and password again, since Zof never shows them. Until you do, Save and use this account says "Re-enter the password to save changes". Saving replaces the saved account. Untick This site needs sign-in to run public checks instead. Test sign-in checks the saved account, but each run verifies it again. If Zof can't tell which application holds your repository, choose it under Sign-in application.
When sign-in can't be proven, Test sign-in says why, and a signed-in test reads Couldn't check with the same reason, never a pass:
- "The protected page looks the same signed out." Choose a page that needs sign-in, or add text shown only when signed in.
- "Signing in didn't work with the saved account." Check the email, password and login page.
- "The page called an address other than your site." If that address is your sign-in service, add it as the sign-in service address. Other services, such as analytics or error reporting, can't be called while signed in.
- "The site sends sign-in to another page or provider (redirect sign-in isn't supported)."
- "The site took too long to load during sign-in." Run it again when the site is responding.
- "Zof couldn't find one email/password form on the login page." Check the login path and the field labels under Advanced.
With a supported saved account selected, Find pages visits protected pages after sign-in and labels them with the account version. It performs no forms or site actions after sign-in. For an end-to-end journey that tests the sign-in itself, choose Test sign-in from signed out and use the placeholders described in Write a user journey.
A test waiting to start keeps the run's saved account version and address, so replacing or removing that account can refuse its Run now, Retry or Start again. Run again and Run this test again sign in with the account as it's saved now, so a fixed account is used straight away. If the account was removed, the new run doesn't start and no public checks run instead. When Run again opens the single-test wizard instead, This site needs sign-in is already ticked and the wizard shows the account as it's saved now, the version the new run uses. If it was removed, save an account there, or untick the box to run public checks. Only the person who created a signed-in group can use its Retry, Run now or Start again actions. Another member can create a new run with their own requester identity.
Check that it worked
The run opens on its own page and updates as each test reports. The header gives the run one word and one sentence, and the test you select shows its stage: Waiting to start, Starting the test, Testing or Collecting results. It also shows how long it has taken and Usually, the middle time of that test's last 20 finished runs on this repository. Usually needs at least 3 runs, and leaves out cancelled, timed-out and errored runs. Timing and traffic tests on the same address take turns, shortest first. A test waiting for its turn reads Queued: its row says Waiting for its turn and its panel names the test of the run testing the address, with the length the run planned for it when it set one. Its time counts from when it started testing, not from the wait.
When a test fails, its results are recorded before Zof's AI explanation of the failure is ready. While that explanation runs, the test's row says Results recorded · AI explanation running, its panel shows the recorded results under the line "Test execution is complete. The recorded results are available while source assistance finishes.", and the header says the same; the progress line counts the tests with results recorded, and findings appear once the run is sealed. The test and the run still say Running until the explanation ends and the run is sealed, and that wait never counts as taking long.
A test counts as taking long at three times its usual time, and at least 10 minutes, or at 30 minutes when no usual time is known. The page then says so, and says how long since the last update when the run's events show it. That is a time rule, not a fault: the test may still finish, or Zof stops it at its time limit. A test shown waiting for its turn doesn't count as taking long.
While a run is going, Cancel run stops it, after you confirm. Tests still going stop, and tests waiting to start never start. To stop one test of several, select it and choose Cancel this test.
A run made from a test in Tests says From test and the test's name, and the name opens that test. When Zof doesn't know the test, the line isn't there.
Everything else on a run sits under More actions: Report or Run again, whichever isn't the page's own button, View on map once it has finished, and Share and Compare for a run of one test. Tests can run in parallel, but timing and traffic tests on the same address run one at a time so they do not distort each other's measurements. A test waiting for proof runs once you prove the address: open Prove the address, then run it, tick the box, then choose Run now. While address proof is off, a test still waiting from before has just Run now. Open a test to see its checks, and, for a failed step, a screenshot when the test captured one. From the run, Logs shows what each test's agent reported, and Compare puts the run beside another one.
All your runs are listed on Runs, with runs still going first. Each row shows the run's word, what it tested, its code, when it started and how long it took. Not reported means nobody sent that fact. From 10 runs, a search box and Filter appear, for status, Started by (All, Manual, Pull request or Schedule) and environment. Save view, Copy link, Export and Compare are under More actions. The environment you pick in the header narrows Runs, Schedules, the release approvers on Roles and the change list on Topology to it, and stays in the page address (?env=) so a shared link shows the same view. The header shows its environment tabs only on those pages and in the new run wizard, which starts on your pick when you open it from one of them. Other pages, Home included, have no environment tabs and show all environments. Your pick is kept, so it applies again when you go back to a page that filters. Pull request rows are Zof's checks on a pull request's head commit, named by the pull request's number and the branch it merges into. They show the test result as recorded, until the pull request has a decision for that commit, as on Releases. The run index doesn't carry a pull request run's test counts yet, so a row shows no count and its run page says Not reported. They also show, when one was recorded, why a run was skipped, such as "Draft PR · runs when ready for review". Each opens its own run page, which links the pull request's decision on Releases. A pull request row shows no environment: the run index doesn't record where the pull request deploys, so the run page shows the environment from the pull request's decision instead, or says the decision mapped none, or that the decision couldn't be read. A run Zof started for the pull request with no author on record shows "Pull request" on the list and "Automatic (pull request)" on its run page. With an environment picked in the header, pull request rows are left out. A row's word and counts match the run page. On Releases, a quality gate with no evidence yet links the pull request run for that commit, such as "Skipped · view run".
Read the result
A finished test shows a factual observation and Next step from its recorded results, including partial observations and warnings. These remain available while an explanation loads or fails. Explain with AI optionally writes a walkthrough and keeps it for that result; opening the page loads an existing explanation and never writes one automatically. Technical diagnostics stay folded.
| The run shows | What it means and what to do |
|---|---|
| Passed | Every check passed on your address. Nothing to do. |
| Issues found | A check or step failed, even if others passed. The test and step that failed say why. Choose Fix on that test, or fix the problem in your app and deploy it, then run again. |
| Couldn't check | Some checks couldn't be judged, or the test couldn't run at all, so the overall result is not a pass. Recorded measurements remain visible. The reason line says which, in plain words, and What couldn't be checked lists each check with its fix when Zof knows one. A short reason says what, for example "Needs a test value", "Needs a login" or "Needs baseline approval". Follow the next step. For waiting visual screenshots, approve their baselines before comparing again; unavailable images need another capture. When Zof's reviewer doubted what the agent reported, the test says "Doubted by review" and the reviewer's reason. A run's own page also reads Couldn't check, never Passed, when the run finished with no results Zof can read, or with some it can't read. That reason names nothing to add: run it again. |
| Not read yet | On Runs only: the run finished and Zof hasn't read its result yet, so it isn't shown as passed. Filter lists it under Couldn't check. Open the run, or look again soon. |
| Cancelled | The run stopped before it finished. Tests that reached a result before it stopped are still charged (see below). Run again. |
A run reads Passed only when every test passed. Otherwise the header shows the word that needs you first and counts the rest, for example "Issues found · 1 of 8" and "Passed 5 · Couldn't check 2". A reason that names a setup problem on Zof's side offers Open help instead of Run this test again.
A pull request run on Runs reads a release word once Control has decided on its commit: Ready to ship, Blocked, Couldn't check, Needs evidence, Being checked or Waiting for approval. A run that failed stays Issues found whatever was decided.
Common reasons a check couldn't be judged, and their fixes:
- A journey step Zof couldn't understand. Rewrite it in the step language. See Write a user journey.
- No API spec. The API contract test needs your site to publish an OpenAPI spec, for example at
/openapi.json. See API checks. - A page that needs signing in. Enter the test account email, password and protected page in Options, or use the saved account, for a supported manual website test, when saved sign-in is available. Otherwise, test a public page. A failed or unsupported sign-in is never counted as a pass.
- A check that needs evidence from inside your system. For example, how data is stored can't be judged from outside and never counts as a pass.
A unit run on a repository with no Jest, Vitest, pytest, PHPUnit or Pest tests reads Couldn't check: "This repository has no Jest, Vitest, pytest, PHPUnit or Pest tests, so unit tests couldn't run. Add a test script, or try a smoke test against your app's address." A repository whose tests use Bun's test runner (bun test) also reads Couldn't check, and says Zof can't run that runner yet, so try a smoke test against your app's address instead. When Zof can't set the repository up for unit tests for another reason, such as tests that need a service other than Postgres or Redis, or a test setting whose name looks like a secret, the run says that reason instead and links to Unit tests. Other reasons a test couldn't run are said in words too, never as a code, for example a failed install of your dependencies or a test script that ran no tests.
Your repository's unit tests read Passed when the suite ran and every test passed, even when coverage of the changed code is unknown: the test then shows coverage on its own line. A fully mapped source change with no executable changed lines says there is no executable code to cover; it never invents a coverage percentage. A bounded list of named tests is marked partial and uses trustworthy full totals. Without trustworthy totals, the count stays unknown. When only totals were recorded, Zof lists no invented test names.
How cancelled runs are billed
A test is charged once it reaches a result (passed, failed or partly failed), even if the run is then cancelled or times out. A test with no result is free. A cancelled or timed-out run's page says how many tests were charged and for how many credits, and lists each one with its result. A test that ran on your company's own AI key also says On your AI key. With none charged, it says "Cancelled before any test reached a result. Nothing was charged." Until the run's charges are final, the page says more may still arrive. If they can't be read, it offers Retry and never says nothing was charged.
While a test runs, and under Technical details once it finishes, its panel shows Credits for this run: what it Held, what its tests Used and what was Returned. Held credits are out of your balance, never also available. Unused credits come back when the run ends, or 6 hours after the hold started ("Returning soon" until then).
If your company runs tests on its own AI key, a run page also says when part of the run used Zof's default model because the key stopped working (those tests were charged at the normal rate), or when the company's model rejected a request Zof sends and that part of the run failed. A cancelled run says so too. See Use your own AI key.
Before you start a run, New Run says when your company's credits are low (about how many test runs are left) or when a run won't start: not enough credits, the spending cap reached, or a payment overdue. It doesn't stop you pressing Run; Zof checks again when the run starts, and runs that are free still start.
Recorded examples during a demonstration
A company admin can enable recorded examples for manual-run demonstrations. If a manual run encounters a confirmed execution failure and a matching successful recording exists, its report shows Demo · Recorded with the original date. These checks describe an earlier run; they do not verify your current app or authorize a release. Choose View actual run and logs to see the current run's results.
Actual assertion failures and findings keep their actual reports. Without a matching recording, the actual report also stays visible. Recorded views omit logs, artifacts and code coverage, and offer no Fix or baseline actions. Run lists, shares and release decisions retain the actual results. The setting is off by default; your company admin can turn it off to restore actual reports throughout the workspace.
Make a report
Members and admins see Report on a run, as its action once it has a result, and under More actions when it needs running again. It stays off while a test is still running. It covers one run, or every test of a run of several. Zof builds the report from the results, seals a copy and opens it.
The report names the repository and the commit, and says how each test ended: Passed, Issues found, Couldn't check, Cancelled, Not run or Not reported. It reads Passed only when every test passed, and it says how many of the tests ran. A check that wasn't judged keeps a test from reading Passed, but a rule that doesn't apply, a test your own suite skipped and a probe Zof's tooling can't offer ("not testable here") don't. A test that couldn't be read is a gap, and the report says it is partial.
Every sentence is Zof's own fixed wording, chosen from the test's codes and counts, so a report can go to someone outside your company. It never repeats what a test's agent wrote, so it shows no addresses, branch names or run IDs, and a person's name only if it is in the repository's own name. A check is named only when Zof has fixed wording for it; the others are counted. A report states what the tests found and decides nothing about release.
Choosing Report again on the same results opens the same copy. If the run can't be read because the test service is down, its newest sealed copy still opens. If a test starts later, the next report is a new copy, and links to the older one keep showing what they showed. On the report, Share makes a link, for a whole run as well as a single test. Download gives you a PDF to read and hand on, or the sealed JSON to check against its hash. The PDF says what the report says and shows no IDs, only the record hash in its footer, and it is named after the repository and the day it was sealed. A very long report can't have a PDF, and a long one may ask you to try again in a few seconds; the sealed JSON still works. A company that limits sharing allows these links under Sealed reports, and a list of shared links types them "Sealed report". Every sealed report is listed on Reports, under Test reports, newest first, and everyone in your company can open them. Each row shows the report's word, the run and commit it covers, how many tests ran, and when it was sealed and by whom. Older copies of a run's report fold under the newest one and read Replaced by a later start. Opening one says so and links the latest.
Run an advisory agent
Some agents are advisory: they report what they find, but Zof records no verification for their runs, so the results are never evidence and never count toward a release. Open Device Emulation Testing in AI Agents to run the compatibility testing agent.
An advisory agent that sends heavy or probing traffic, such as DAST or API fuzzing, follows the same address proof as New run. Address proof is turned off for now, so it runs on any address you enter. When it's back on, its form shows Prove the address and I'm authorized to test the address, and Zof checks both again when it starts.
Choose a connected Repository, a Branch and the address where your app runs. The Repository starts as the one you chose in New run, else the header's project, so the run is filed under it; a repository that isn't connected selects none. Choose Add page paths for this run and enter page paths, or select Choose stored compatibility cases. Set the browser engines, emulated devices, orientation and coverage. You can also supply a readiness selector, extra checks and custom viewport sizes. The browsers and devices you select apply to every test in the run, including a stored case whose text names others.
The Endpoint fills from that repository's saved address when the field is empty. You can edit it; changing repositories replaces an automatically filled address, while an address you typed stays as entered.
The report shows the combinations that ran, skipped combinations and their reasons, assertion failures, actual engine versions and timings. Full coverage cannot pass after silently omitting requested combinations. Mobile profiles are browser emulation; they do not certify physical devices or a particular phone operating system.
To test a native Android or iOS app instead, choose Mobile app (Android & iOS) under What are you testing? at the top of Device Emulation Testing. The manual run's compatibility options link there too. Choose a Repository and Branch, then paste the Build URL: an https link to an Android debug .apk, or to a zipped iOS simulator .app (not an App Store .ipa). Choose the Devices and Orientation. You can add up to 10 Screens, each opened by its deep link (the launch screen is always captured), and up to 50 Text checks that must be visible or hidden. It needs no web address. The report shows a screenshot and a result for each device and screen. Tests lists each device and screen as its own test; one that wasn't judged shows an error, never a pass. The app runs on Appetize virtual devices, not physical phones, and the results are advisory. When a run can't start because of a problem on Zof's side, the report says so instead of pointing at your build.
When the agent reports a rendering matrix, Tests lists each measured page, browser and device combination with its own checks and elapsed time where recorded. Interrupted combinations show an error, and skipped combinations show their reason; neither counts as a pass. Without rendering details, Zof does not invent test results.
The displayed source commit identifies the repository revision you selected. A supplied address may serve a different build: without served-build confirmation, that association stays unverified. Its Technical details show Commit served only for a build Zof served itself and whose own log confirms the commit; a commit that was only stated shows as "Commit declared by you (not verified)". When the build's log is missing, or no commit was stated, they show Commit at this address: "Not confirmed". The run page remains marked Advisory run, never evidence or a release input. Automatic UI-change workflows can also select compatibility when advisory runs are enabled and the configured budget permits it. The general New run and schedule wizard offers verification tests; compatibility uses this dedicated manual tool. Native compatibility schedules are available through the orchestrator API.
Some runs also show Testing assistance below the results. Each entry is a supplemental investigation: an AI explanation (advisory), a Generated check, or a Supplemental check execution that ran it in the sandbox. An AI explanation appears when an orchestrated run fails, once for the whole run, however many parts it has. An AI model reads your code at the reviewed commit and explains likely causes: a summary, each finding with its category and severity, the source lines it cites, and what it couldn't tell. A link opens each line at the reviewed commit or at the base commit. When it can't cite a line of your code, it says "Couldn't determine a cause" instead of guessing. An AI explanation does not prove an executed reproduction, and none of these entries ever changes the recorded test results. While assistance is still running, the recorded results are already available.
When a test's wording isn't something the agent's own rules can read, the run may show Read with AI help. An AI model rephrased only those sentences into the agent's own wording, and Zof checked that every number, quote and "not" stayed the same before the agent used them. Each row names the test, your sentence and the wording it was read as. The agent's own checks decided the result, never the AI. Each run has an AI reading budget: once it is used, the agent's notes say "AI reading budget for this run is used", and the rest of the run uses only the agent's rules. Wording the rules can't read is then reported as needing more information, never as a pass. A company admin can turn AI help off: see Use your own AI key.
Run again
On a finished test run, choose Run again. A single-test wizard opens with the same repository, commit, address and test type. A unit test run opens New run with the repository chosen and unit tests ticked instead. For the API contract test and the end-to-end test, step 3 is filled in with that run's endpoints or journeys. Pages go back to their defaults. In a run with several tests, each finished test also has its own Run again, which runs just that test again on the run's commit.
When a run failed because of code, Fix opens the fix drawer. Codex is the default; you can instead choose Claude Code, DeepSeek or Kimi with your own API key, unless your admin turned that provider off. A standalone test needs a target branch that still points to its tested commit before Zof writes a fix and opens a draft pull request. See Fix a failure with Codex or your own API key.
When a run has finished, View on map opens the system map. For a pull request run whose change the System Graph knows, it shows the services that change touched and reached at the commit the run tested. For any other run it shows the run's repository, or the whole map when the graph doesn't name that repository yet.
Limits
- A run takes at most 12 tests. A schedule has no limit: each test gets its own schedule.
- Each run checks up to 10 pages, up to 10 endpoints, or up to 5 journeys. A SQL injection scan takes up to 5 pages.
- Pages, endpoints and journeys must stay on the address you're testing.
- Pages that need signing in aren't supported yet, and journeys can't type passwords.
- Address proof for the load, stress, scalability and endurance (soak) tests and SQL injection scan is turned off for now, so they run on any address you enter: make sure it's one you may send load or attack traffic to. When Zof turns it back on, they need a verified address again. Stress allows at most 200 peak users and 300 seconds including recovery confirmation; scalability allows 2–10 increasing steps up to 200 users and at most 900 seconds total. Smaller measurements may not meet standard verification's minimum traffic requirements; the form and review show that separately. Once address proof is back on, an address your repo's GitHub deployments reported is verified already; otherwise verify it with a file or a DNS record from the Run page. See Verify your address.
- These tests run on demand only, with address proof on or off: Schedule is off while one is selected. Unit tests can't be scheduled yet either.
- A test marked Disabled in Tests doesn't run. Zof refuses a new run, a schedule's Run now or a New run setup on its repository until you enable it, and pull request checks for this test are skipped, though unit tests may still run. Zof asks you to confirm before it disables a test bound to a repository. The check doesn't pass because of this: what it shows is up to your company's rules, and a required test with no result blocks the release. Agents already started finish.
- The payment idempotency test also needs a payment test mode on the address: a payment lab, or your company's payment test-mode adapter. Live keys are refused. New run offers it only when your company has a payment test-mode adapter set up (a company admin sets it up from that card in New run: Set up payment test mode); otherwise its card is unavailable and says why.
- The regression test needs a baseline first: open a passing run of the repo and choose Use as baseline. It then compares another address of the repo with the baseline's address, never the same one.