Benjamin Cane

#Bengineering 🧐

Short-form distributed-systems tradeoffs, reliability patterns, lessons learned, and leadership notes — shared weekly.

33 posts August 8, 2025 → March 26, 2026
Portrait of Benjamin Cane

Subscribe to:

#Bengineering 🧐

Prefer your posts in a reader? Subscribe to the RSS feed or catch me on LinkedIn.

RSS Feed LinkedIn

Latest Drop

Portrait of Benjamin Cane
Benjamin Cane
March 26, 2026

Generating code faster is only valuable if you can validate every change with confidence.

Software engineering has never really been about writing code. Coding is often the easy part.

Testing is harder, and many teams struggle with it.

As tools make it easier to generate code quickly, that gap widens. If you can produce changes faster than you can validate them, you eventually create more code than you can safely operate.

Which begs the question: What does good testing actually look like?

🔍 What Good Looks Like

One of the biggest challenges I see is that teams struggle to understand what “good” testing means and never define it.

Pipelines are often built early in a project, when the team is small, and they rarely keep pace with the system and organization as they grow.

My starting principle is simple:

  • At pull request time, you should have strong confidence that the change will not break the service or platform being modified.

  • Within a day of merging, you should have strong confidence that the change hasn’t broken the full customer journey that the platform supports.

🔁 On Pull Request

For backend platforms, I like to see three levels of automated testing before merging.

Code Tests (Unit Tests)

This level is the foundation. Unit tests validate internal logic, error handling, and edge cases. Techniques such as fuzz testing and benchmarking also reveal issues early. As the test pyramid tells us, this is where the majority of testing and logic validation should take place.

Service-Level Functional Tests

Too many teams stop at unit tests for pull requests. Functional tests should also be run in CI for every pull request.

Services should be tested in isolation with functional tests. Dependencies can be mocked, but things like databases should ideally run for real (Dockerized).

This is where API contracts are validated and regressions can be identified without wondering whether the issue came from this change or another service.

Platform-Level Functional Tests

Testing a service alone isn’t enough. Changes can break upstream or downstream dependencies. Platform-level tests spin up the entire platform in CI and validate that services interact correctly.

These tests ensure the platform continues to work as a system.

For platforms with strict latency or resiliency requirements, I recommend introducing light stress tests at both the service and platform levels. These aren’t full performance tests, but they act as early indicators of performance regressions.

If these three layers pass, you should have high confidence in the change. But not complete confidence.

🌙 Nightly Testing

Some failures take time to appear.

Memory leaks, performance degradation, and cross-platform integration issues may not show up immediately.

That’s why I like to run a nightly build (or every few hours).

This environment runs end-to-end customer journey tests, performance tests, and chaos tests.

These are typically the same tests used during release validation, but running them continuously accelerates feedback. If something breaks, you learn about it early, before the pressure of a release.

🧠 Final Thoughts

There is no universal approach everyone can follow.

Different systems have different needs; mission-critical systems may focus heavily on correctness and resilience. Non-mission-critical systems may focus more on validating core functionality.

Your testing strategy depends heavily on architecture, dependencies, and operational constraints. But if your organization is increasing its ability to generate code quickly, your testing capabilities must evolve at the same pace.

AI-generated code becomes much easier to review when you already have high confidence in your testing.

Previous Posts

  • March 19, 2026 When You Go to Production with gRPC, Make Sure You’ve Solved Load Distribution First
  • March 12, 2026 You may be building for availability, but are you building for resiliency?
  • March 5, 2026 When your coding agent doesn’t understand your project, you’ll get junk

Archive

  • March 26, 2026
  • March 19, 2026
  • March 12, 2026
  • March 5, 2026
  • February 26, 2026
  • February 19, 2026
  • February 12, 2026
  • February 5, 2026
  • January 29, 2026
  • January 22, 2026
  • January 15, 2026
  • January 8, 2026
  • January 1, 2026
  • December 26, 2025
  • December 19, 2025
  • December 12, 2025
  • December 5, 2025
  • November 28, 2025
  • November 21, 2025
  • November 14, 2025
  • November 7, 2025
  • October 31, 2025
  • October 27, 2025
  • October 24, 2025
  • October 10, 2025
  • October 3, 2025
  • September 26, 2025
  • September 19, 2025
  • September 12, 2025
  • September 5, 2025
  • August 22, 2025
  • August 15, 2025
  • August 8, 2025

Made with Eleventy and a dash of #Bengineering energy.