Skip to content

Developer Tests

Ed Mozley edited this page Oct 4, 2026 · 2 revisions

πŸ§ͺ Developer Tests

FreeITSM ships a suite of PHP test scripts in tests/. They are developer tooling, not part of the application β€” if you run FreeITSM rather than work on it, you never need to touch them.

This page is the index. Each test has an entry on one of the pages below saying what it covers, how it works, how to run it, how to read its output and what to do when it goes red.


πŸš€ Running a test

From the repository root, on the command line:

php tests/field-widths-agree.php

Most print one line per assertion and a count at the end:

  ok    the default is one of the permitted widths
  FAIL  form-logic agrees with the service  β€” service=12,9,8,6,4,3  logic=12,9,6,4,3
============================================================
43 passed, 1 failed

The exit code is 0 when everything passed and 1 when anything failed, so a test can be used in a script or a CI job without parsing its output.

πŸ”΄ They never run over the web

Every script starts with:

if (PHP_SAPI !== 'cli') { http_response_code(404); exit; }

Do not remove it. FreeITSM is normally deployed by putting the repository in the document root, so without that line a request to /tests/<anything>.php would run the file β€” and these tests write to the real database, creating forms, assets, documents and working analyst accounts. See Test suite exposure for the whole story and the three layers that now keep the directory closed.

⚠️ Most of them use your real database

A test that needs data creates its own, prefixed ZZ/zz, and deletes it in a finally block. Several assert the cleanup rather than assume it. Even so: run them against a development database, not a production one. A test that dies part-way leaves its rows behind.

Each entry below says whether a test needs a database, needs the network, or needs nothing at all.


πŸ“š The pages

Page Covers
Forms Field identity, conditional visibility, layout and widths, drafts, lookups, audiences, CSS class collisions
Assets & CMDB Import, custom fields, physical disks, last-seen repair, typed CMDB fields, contract links, reconciliation, tags, labels, Proxmox and Cloud Director sync
Knowledge, search & documents Article visibility and ACLs, gap analysis, the search corpus, text extraction, document permissions
Tickets & tasks Ticket numbering, email threading, saved table views, task priority, recurrence, collaborators, calendar sync
Security & access The security-findings suite, record previews, SSO/LDAP/OIDC, directory sync scopes
Integrations & external services Jira and Azure DevOps, AI providers, CalDAV, mailbox folders, the inventory agent
System & infrastructure Database verification indexes, config.php, container detection, UTC handling, the status portal
Test suite exposure Why tests/ is unreachable over HTTP, and the guard that keeps it that way

🧭 House conventions

These recur throughout the suite and are worth knowing before you read or write one.

A test explains why it exists. The docblock names the failure it was written after, not just the behaviour it asserts. That is what makes a red result actionable years later.

Every negative assertion has a positive control. "The required field did not block submission" proves nothing on its own β€” it is equally true of a harness that never validated anything. So the suite pairs it with "…and this one DID block". If you add a check that something is refused, add the control too.

A checker must be able to fail. Several tests assert their own matcher works β€” that it sees a real match and does not see a near-miss. This is not belt-and-braces; it has caught real faults. One check was satisfied by its own explanatory comment and passed against the very bug it was written to catch.

A skip says so. A section that cannot run β€” no headless Chrome, a missing table, no fixture server β€” prints SKIPPED and the reason. It never counts as a pass. Chase a skip; a suite that is quietly skipping half of itself looks exactly like a suite that is passing.

Green means what it says, and no more. Some tests carry an explicit warning about what they cannot prove. tests/azure-openai/run.php ends with one: it proves FreeITSM sends what Azure asks for, not that Azure accepts it.


✍️ Writing a new test

  1. Start with the CLI guard. php tests/web-exposure-guard.php will fail if you forget it, and it walks the directory rather than a list, so a new file is checked the moment it exists.
  2. Write the docblock before the assertions: what has to hold, and what went wrong that made this worth writing.
  3. Use the check(label, bool, detail) helper shape the rest of the suite uses, and end with the $pass/$fail summary and exit($fail === 0 ? 0 : 1).
  4. Clean up in a finally, and assert the cleanup.
  5. Add a control.
  6. Add it to the right page here.

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally