Run

QA and Software Testing for Drupal

Automated tests, static analysis and accessibility checks that run in your pipeline and block a failing release, on Drupal systems we built and ones we inherit.

An engineer reads it and replies within one business day.

  • Automated tests on key business paths
  • CI that blocks a failing release
  • Docs so your team can extend the tests

Software testing done only before launch describes a system on one day. The next change, made by somebody who was not there, can quietly break a permission, a form or an integration, and nobody finds out until a user does. We build automated tests into the code: unit, kernel and functional tests in PHPUnit, browser tests in Playwright, static analysis with PHPStan and PHPCS, all running in the CI pipeline so a failing release is stopped before it ships. On a codebase we did not build, we start with the part your team is most reluctant to change.

Who this is for
A team shipping often enough that manual regression testing no longer keeps up. A codebase inherited with no tests at all. A release that broke something nobody thought to check. A Drupal upgrade ahead that the team wants to be able to verify.
Empty clipboard and a pencil on a wooden desk, seen from above
A test plan says what is covered, and what is deliberately left out.

What you get

  • Automated test suites on the paths where a regression would cost money or trust
  • Static analysis and coding standards enforced in CI with PHPStan and PHPCS
  • Accessibility checks in the pipeline, run on every build
  • Performance checks on real pages with realistic data volumes
  • A CI pipeline that blocks a failing release
  • A test plan written against the requirements, including what is deliberately out of scope
  • Documentation so your team can extend the suites

Coverage is reported by the paths that matter to the business, not as a single percentage, so you can see what is protected and what is not yet.

Sample Test coverage by critical path example.org · Drupal 11

PathTestsRunsStatus
Log in and password resetFunctional, PHPUnitEvery merge requestCovered
Editors cannot publish without reviewKernel, PHPUnitEvery merge requestCovered
Event registration and paymentEnd-to-end, PlaywrightStaging, before releaseCovered
Search results pageAutomated accessibility checkEvery buildCovered
Contact sync to the CRMContract test on a recorded responseEvery merge requestPlanned next
Send us the repository

An engineer reads it and replies within one business day.

How the work runs

Quality assurance is part of how the code is written, not a phase at the end, so the same steps apply whether we are building the system or adding tests to one that exists.

How test coverage is built

  1. Audit What the code does, where the risk concentrates, and whether the repository matches what is deployed. You keep the assessment
  2. Plan A test plan against the requirements, with what is deliberately left out. You keep the test plan
  3. Cover Tests for the riskiest paths first, then outward. You keep the test code
  4. Pipeline The suites wired into CI, so a failure blocks the release. You keep the pipeline configuration
  5. Handover Your team writes a test with us reviewing it. You keep the documentation

Software testing for Drupal: what we automate

Developers find bugs by running the thing. Tests are written so that a change made a year from now, by somebody who was not there, does not quietly break something nobody thought to check. That decides what is worth testing: the parts where a silent failure would be expensive.

Test pyramid for a Drupal codebase

Test pyramid for a Drupal codebase Unit tests at the base, then kernel tests, functional tests, and end-to-end browser tests with Playwright at the top. End-to-end Playwright Functional Pages and forms Kernel Services and database Unit Pure PHP logic
  • Permissions and access. Every role, against every protected route and entity. In an application such as CreAct, which we built for several companies working in one system, each company must see only its own records, and that is the kind of rule a test should guard.
  • The paths that carry money or commitments. Checkout, booking, submission, approval. Tested end to end in a browser with Playwright, not only at the unit level.
  • Integrations. Contract tests against what the external system returns, so that when it changes, your build tells you before your users do.
  • The content model's rules. Required fields, workflow states, what an editor is prevented from doing. These usually live in configuration, and configuration drifts without anyone noticing.
  • Upgrade surfaces. Custom code that touches Drupal APIs, so the next major version is a routine piece of work instead of an investigation. The modules we maintain on Drupal.org face the same question at every major version; WE Mega Menu now has a release for Drupal 10.3, 11 and 12.

Testing a system you did not build

Adding tests to an existing codebase is a different job from writing them alongside a build. There is rarely budget to cover everything, so we begin where the risk is: the part of the system your team avoids touching.

The first tests record what the code does today, right or wrong. With that behaviour pinned down, a fix changes only what it was meant to change. Coverage is then built outward from the risky parts, and static analysis sorts the problems that can be fixed mechanically from the ones that need a decision. Tests nobody runs buy confidence that has not been earned, so the pipeline runs them and blocks a bad release.

Accessibility checks in the pipeline

Every build runs automated accessibility checks on the templates: images without alternative text, form fields without labels, contrast below WCAG AA, headings out of order. They catch regressions the day they are introduced.

What automation cannot judge is whether a page makes sense to someone using a keyboard or a screen reader. That is the work of an accessibility audit, which tests against WCAG 2.2 with a keyboard and a screen reader and reports findings by component.

What it costs

Adding tests to an existing codebase is scoped from the size of the code and how much of the risk you want covered, and it is staged: the assessment first, then the critical paths, then the rest if it earns its place. You can stop when the risk is covered rather than when a budget runs out. The work is priced from the QA, Security and Accessibility Engineer rate on the pricing page.

On projects we build, test coverage is part of the work and of the project price, not a separate purchase.

Terms that hold

These terms hold across our services; where a service starts differently, its page says how. The full wording is on the warranty page and in why you own the source code.

  • A prototype before you sign a build Before a build project is signed, we build a prototype at no charge: a design, a clickable prototype or a working demo on real code, so you decide against something real.
  • You receive the system and its source code Custom work is yours from the first commit: the repository, custom modules, theme and deployment configuration. When we build your system on one of our platforms, you receive the whole system and its source code as well.
  • A warranty on development work Development projects carry a 1-year warranty by default, up to 3 years. It covers defects in what we built, and applying the security releases of Drupal core and contributed modules while the warranty runs. Maintenance picks up where the warranty leaves off.
  • Response targets we publish A first response in 4 hours for critical issues, 1 business day for high priority and 3 business days for normal. Support runs in business hours; cover outside them is an option, priced separately.

Questions we get asked

What coverage percentage should we aim for?

None in particular. Coverage is a poor target, because the easiest code to cover is usually the least likely to break. A high percentage across simple code is worth less than complete coverage of checkout, authentication and permissions.

Do you do manual testing and user acceptance testing?

Yes, for what automation cannot judge: exploratory testing of new features, and user acceptance testing against the agreed scope before a release. Acceptance is run with your people, because they decide whether the work is accepted.

Will tests slow our releases down?

The quick checks run on every merge request and the slower browser tests run once, before promotion to production, so developers are not kept waiting. And nobody has to repeat a manual regression pass before each release.

Is this the same as a security audit?

No. Quality assurance gives confidence that the system still does what it should after every change. A security audit looks specifically for the ways Drupal sites are compromised: modules behind security releases, permissions, text formats and server configuration.

Can you test performance before a launch?

Yes: load and page-speed checks on real pages with a realistic volume of content, so the numbers describe the site people will use rather than an empty install.

Which browsers do the tests cover?

Playwright drives Chromium, Firefox and WebKit, the engine behind Safari. Which of them run on every release, and on which screen sizes, is agreed per project against the browsers your visitors use.

Not covered here? Ask us directly.

Send us the repository

An engineer reads it and replies within one business day.

Tell us what you are afraid to change

That answer points at where the coverage is missing. Send us the repository or describe the system, and we will say what is worth testing first.

An engineer reads it and replies within one business day.