Migration assurance

Proving a content migration lost nothing

Moving a site between content platforms is easy to do and hard to prove. I built the test suite that checks the pages, the metadata and the content against a source of truth — and reports every failure as data.

Availability, then metadata, then content — a failure upstream stops the noise downstream
3 dependent suitesAvailability, then metadata, then content — a failure upstream stops the noise downstream
Retries only for specific network conditions, so flakiness cannot hide a real defect
0 blanket retriesRetries only for specific network conditions, so flakiness cannot hide a real defect
Every failure emitted as a structured record, not a screenshot
Failures as dataEvery failure emitted as a structured record, not a screenshot

The client

A large web estate migrating from one content management platform to another, staged behind a content delivery network, where the risk is not that the site breaks but that it quietly loses pages, metadata and search visibility.

The engagement

An automated verification suite in three dependent stages, run against staging before anyone signed off the migration.

The problem

A platform migration produces a site that loads. That is the trap. What actually goes missing is unglamorous and expensive: a canonical link, a meta description, an alt attribute, a legacy URL that no longer maps, a component that renders empty because its content did not come across. None of it is visible to someone clicking around, and all of it is visible to a search engine within weeks.

What I did

I made the suite argue with the migration rather than confirm it. Expected content and URL mappings live in a declared source-of-truth file, so tests compare against a stated intent instead of against whatever the new site happens to contain. The three stages are explicitly dependent — if basic availability fails, the metadata and content suites do not run, which stops a single outage from producing hundreds of misleading failures. Element targeting is restricted to stable test identifiers rather than styling selectors, with the deliberate exception of metadata, so a design change does not masquerade as a migration defect. Blanket retries are set to zero, with retries permitted only for specific network status codes, because a suite that retries everything is a suite that hides intermittent real breakage. And failures are emitted as structured records rather than as prose, so the migration team gets a list they can work through rather than a report they have to read.

What was built

Three test projects with explicit dependencies — availability and static assets first, then search metadata including titles, descriptions, canonical links and image alt text scoped to the main content region, then content and interface checks with legacy URL mapping validated against a source-of-truth file, including component-level diagnostics through the platform's own interface and the search backend.

On the table at the end

  • Three-stage automated suite with declared dependencies
  • Source-of-truth file for expected content and URL mapping
  • Structured failure report emitted per run
  • Targeting and retry policy written into the suite

What it changed

Replaced 'the site looks fine' with evidence: availability, search-critical metadata and content compared against a declared source of truth, with every failure written out as structured data rather than as a screenshot in a chat thread.

How it ran

  1. 01

    Declare the source of truth

    Expected content and legacy URL mapping written into a file, so tests compare against intent rather than against the new site.

  2. 02

    Stage the suites by dependency

    Availability first; metadata and content only run if the basics pass, so one outage does not generate hundreds of false failures.

  3. 03

    Protect search visibility explicitly

    Titles, descriptions, canonical links and image alt text checked as their own suite, scoped to the main content region.

  4. 04

    Target stably

    Test identifiers rather than styling selectors, so a redesign is never mistaken for a migration defect.

  5. 05

    Refuse to retry the truth away

    No blanket retries; retries only for specific network conditions, and every failure emitted as a structured record.

Something similar on your plate?

Thirty minutes, no deck. I will tell you whether it is worth doing at all.