Latest / The Tech Career Podcast with Fexingo: Engineering Jobs, Interviews, and FAANG Career Strategy / How FAANG Engineers Use Unit Tests as Debugging Documentation
Transcript
- Lucas: A few weeks ago I was talking to a senior engineer at Google who told me something that stuck. She said the single biggest productivity boost for her team wasn't a faster build system or a new code review tool. It was making sure every pull request included meaningful unit tests. Luna: Meaningful as in not just hitting a coverage number? Because I've seen teams game the percentage by testing trivial getters. Lucas: Exactly. She meant tests that actually document how the code is supposed to behave. Her argument was that a well-written test is the clearest form of documentation an engineer can leave behind. It's executable, it never goes stale, and it tells you exactly what the author expected to happen. Luna: So it's documentation that also catches regressions. That's the ideal, but I've also seen it slow things down. If you're shipping fast, writing those tests can feel like overhead. Lucas: That's the tradeoff we're going to dig into today. Because I think the framing around unit tests is often wrong. People see them as a quality gate — something you do before merging to prevent bugs. But the more I talk to engineers who've been through real production fires, the more I hear that unit tests are actually a debugging tool. They're not primarily about prevention. They're about diagnosis. Luna: Diagnosis. I like that. Walk me through how that works in practice. Lucas: Let's say a service goes down at 2 AM. The on-call engineer sees an error they've never encountered. They open the codebase and start reading the source. That's slow. They're trying to reconstruct the author's mental model. But if that module has a comprehensive test suite, they can look at the test file first. The test names tell them what the function is supposed to do. The test inputs show edge cases the author considered. They can run the test against the failing production data and see exactly where the expectation breaks. Luna: So the test becomes a map of the terrain. Instead of wandering through the code, you know right where to dig. Lucas: Right. And this isn't hypothetical. I remember a specific incident at Uber a few years back. Two teams owned adjacent microservices handling fare calculation. One team had near 90 percent test coverage with explicit test cases for things like surge pricing caps and split-fare edge cases. The other team had maybe 40 percent coverage — just happy-path tests. When a pricing bug hit, the well-tested team root-caused it in about 20 minutes. The other team took almost four hours. Same company, same incident, same compensation. Luna: Four hours versus twenty minutes. Night and day. And I bet the second team's engineers were more stressed the whole time. Lucas: Absolutely. And that stress is a real cost. It burns people out. It erodes confidence in the system. So when we talk about unit tests as debugging documentation, we're talking about reducing cognitive load during the worst possible moments. The test suite is a safety net that also tells you where the net is. Luna: I want to push back a little though. Because writing comprehensive tests takes time. If you're a junior engineer trying to hit a deadline, or you're in a startup where speed is everything, that investment is hard to justify in the moment. Lucas: It is. And I'm not saying every line of code needs a test. But here's a heuristic I've heard from multiple staff-plus engineers: if you are fixing the same category of bug for the second time, write a test for it. The third time, you've already paid the cost of not having the test in debugging time. The test would have been cheaper. Luna: So it's a compounding investment. The first bug is cheap to fix. The second is a signal. By the third, you're losing money. Lucas: Exactly. And this ties directly into how promotions are evaluated at FAANG companies. The engineering ladder isn't just about shipping code. It's about raising the bar for reliability and reducing toil for everyone. If you can show that your test suite saved the team hours of debugging during an incident, that's a concrete example of impact at scale. Luna: I've heard of engineers using test coverage improvements in their promotion packets. But more as a metric, not as a narrative. Lucas: Right, and that's the mistake. The metric alone is weak. But the story of a specific incident where your tests made the difference — that's powerful. 'I wrote tests for the payment reconciliation module. When a currency conversion bug hit, the on-call engineer used my test to isolate the issue in fifteen minutes. Previously, similar incidents took over an hour.' That's a narrative, not a number. Luna: Quick honest thing — this kind of conversation is exactly why we keep making these episodes. A handful of listeners chip in monthly through buy me a coffee dot com slash fexingo, and that's literally what funds making this many of these. No ads, no sponsors, just people who find the content useful. So if you've gotten something out of the show, that's how you can keep it going. Lucas: Yeah, it's a small group that makes a big difference. And it means we can talk about whatever we think is actually useful, not what a sponsor wants us to say. Anyway, back to unit tests as documentation. There's another angle I want to explore: how this practice changes the way you write code in the first place. Luna: You mean test-driven development? Writing the test before the implementation? Lucas: Exactly. When you write the test first, you're forced to define the interface and the expected behavior before you get attached to any particular implementation. It pushes you toward simpler, more modular designs. Because if the test is hard to write, the code is probably too coupled. Luna: That's a great signal. If you can't easily set up the test, your code might need refactoring before it even works. Lucas: Right. And think about the debugging benefit again. If you wrote the test first, you know exactly what the expected behavior is. When something breaks, you can compare the actual output to the test's expected output. The diff tells you what changed. No need to trace through the whole function. Luna: So it's like having a before and after snapshot for every change. Lucas: Exactly. And this is why some teams require test changes in the same commit as code changes. It makes the code review easier too. The reviewer can look at the test and understand what the author intended before even reading the implementation. That's a huge time saver. Luna: I've seen that backfire though. Sometimes the test passes but the implementation is wrong because both are written by the same person with the same misunderstanding. Lucas: That's a real risk. But it's mitigated by having the test be reviewed independently. The reviewer should ask: does this test actually capture the right behavior? And that's where domain knowledge comes in. A good reviewer will catch a test that only checks the happy path. Luna: So the test becomes a shared understanding between author and reviewer. That's more collaborative than just reading code. Lucas: Yes. And it's also a teaching tool. Junior engineers on my team used to struggle with understanding the codebase. I started pointing them to the test files as a starting point. Suddenly they were asking better questions. They could see the edge cases I'd thought about, the inputs I'd used. It accelerated their ramp-up time significantly. Luna: That's a concrete benefit. How much faster? Lucas: I'd estimate roughly 30 to 40 percent faster to their first meaningful contribution. Because they weren't just reading abstract code. They were reading examples of what the system actually does. Luna: So unit tests serve as a kind of executable tutorial for new team members. Lucas: Exactly. And that's a force multiplier. Your code lives longer than you're on the team. The tests you write today will be read by someone two years from now who's trying to fix a bug at 3 AM. You're essentially leaving them a note that says 'here's what I expected to happen, good luck.' And that note can save them hours. Luna: I think there's a parallel here to the concept of 'documentation-driven development' that some teams use for design docs. You write the doc first, get alignment, then code. Tests are a similar forcing function. Lucas: Exactly. And just like design docs, tests are a form of communication. They're not just for the computer. They're for the next human. That's why I think the debugging documentation framing is so powerful. It reframes the investment from 'I have to write tests' to 'I get to leave a map for my future self and my teammates.' Luna: I want to go back to the promotion angle. You mentioned narrative earlier. How would you actually structure that in a promotion packet? Lucas: Good question. You'd start with the problem: the team was spending too much time debugging production incidents because the codebase lacked test coverage. Then you describe your action: you drove an initiative to add meaningful tests to the critical path modules, focusing on edge cases and failure modes. Then you show the result: two specific incidents where your tests reduced mean time to resolution by X percent. And importantly, you show that this became a lasting practice — the team adopted your test patterns for new code. Luna: That's a clear before and after story. It shows leadership, technical judgment, and impact. Lucas: Exactly. And that's the kind of thing promotion committees love. It's not just 'I wrote tests.' It's 'I changed how the team works and made everyone's life better.' Luna: So if someone listening wants to start shifting their practice toward this debugging-documentation mindset, what's the first step? Lucas: Pick one module that has given you trouble in the past. Maybe it's a payment processor, maybe it's a data pipeline. Write tests for the three most common failure modes you've seen. Then the next time something breaks, see how much faster you can diagnose it. I bet you'll be sold. Luna: And if the bug never comes? You still have better documentation and higher confidence. Lucas: Exactly. It's a win either way. And over time, you build a suite that becomes the team's go-to reference for how the system should behave. That's the kind of legacy that gets remembered in performance reviews. Luna: Alright, I'm convinced. I think I'll start with that payment module I've been avoiding. Lucas: Do it. And let us know how it goes. We might do a follow-up episode on test patterns specifically. But for now, I think the core idea stands: unit tests aren't just a gatekeeping chore. They're the best debugging documentation you'll ever write.