Restoring Confidence in a Legacy System with Incremental Test Coverage

Context

This case study focuses on a legacy frontend application that remains critical to the business. It is an AngularJS 1.8 application that still powers approximately 75–80% of the reports used by customers today.

AngularJS is fundamentally different from modern Angular — not just syntactically, but architecturally. Dependency injection, services, and application structure follow patterns that are no longer common practice. As community support has faded and fewer engineers have direct experience with AngularJS, much of the practical knowledge required to work safely in this codebase has eroded.

While documentation exists online, it is increasingly difficult to distinguish legacy AngularJS guidance from modern Angular resources, further increasing the barrier to entry for engineers unfamiliar with the ecosystem.

The Problem

Despite being business-critical, this system had no meaningful test coverage and very little documentation. As a result, there was no shared confidence in making changes — neither from the engineering team implementing them nor from product stakeholders approving them.

Small changes frequently caused regressions in unexpected areas. Each update required a full manual regression of the application, which made development slow and risky. Over time, this led to a feedback loop:

  • The system was considered “stable”
  • Because it was “stable,” it was touched as little as possible
  • Because it was rarely touched, knowledge of how it worked continued to decay

Even engineers who had prior AngularJS experience used it infrequently enough that their familiarity steadily degraded. The application increasingly functioned as a black box.

Constraints

A full rewrite was not viable.

  • The original authors had long since left the company
  • There was little institutional knowledge remaining
  • The system’s surface area was large and tightly coupled
  • The risk of unintended breakage was high and poorly understood

Any attempt to modernize or replace the system without first understanding its behavior would have introduced significant risk to a core customer-facing product.

Strategy: Incremental Test Coverage as Risk Reduction

At the start of this effort, the test suite consisted of a single file containing only a comment indicating that tests might be added in the future.

Rather than attempting broad refactors or large-scale changes, I focused on introducing tests incrementally, using them not just as validation tools, but as a way to document behavior and establish trust in the system.

The goal was not exhaustive coverage, but strategic coverage:

  • Identify critical user paths and core report functionality
  • Capture existing behavior as-is, even when the implementation was imperfect
  • Use tests to define the current contract of the system before attempting change

By treating tests as executable documentation, we were able to safely explore the codebase, surface hidden dependencies, and make previously opaque behavior explicit.

Outcome

This approach transformed how the team interacted with the legacy system.

  • The test suite has grown to ~300 tests, with coverage trending upward
  • Engineers now have a safety net when making changes
  • Regressions are caught earlier and more reliably
  • Knowledge that previously existed only as tribal memory is now codified

Perhaps most importantly, this work is restoring confidence. The system is no longer avoided by default, and future efforts — including potential migrations — are now grounded in an clearer understanding of how the application actually behaves

Reflection

Legacy systems don't fail because they are old -- they fail when organizations lose the ability to reason about them.

By introducing incrememental test coverage, we are reducing risk without requiring a rewrite, preserving institutional knowledge, and creating a foundation for future change. This work reinforces the idea that tests are not just a quality mechanism, but a powerful tool for organizational resilience.