Is a Healthcare Career Right for You?

Take the Free Quiz



TDD and Agile: The Big Picture

If you think you are working with agile and most of the features you develop aren’t being used, or if you spent longer than 6 months working on a product that gained no traction, then your implementation of agile is wrong. In fact it could be argued that you are not using agile. Holding scrum meetings does not make you agile. There are companies that spend months in a planning phase, documenting and gathering requirements and specifications, and then think they are agile just because they hold scrum meetings, have a board with user stories, and use the word “sprint” to characterize their work weeks or months. Most of us can see the folly in this, but simply using agile as a software development tool without regard for its usefulness in guiding the direction of the business is also missguided.

The point of agile is to reduce waste (or time, effort and money) by as much as possible. Agile/lean do this by providing a way in which the dev team can help the business test an assumption about the market. In many cases this entails the quick delivery of a crude, possibly buggy package with tech debt to a sub-segment of your users, and then you wait and see if your users actually engage the new feature/package. Once you open up the new package (perhaps a new feature, new landing page, or a full rebranding) to your users, you will see if your market hypothesis holds water. If it does then you pay the tech debt and really invest the time into ironing out all the kinks of the new thing you released, which (again) could be anywhere from a branding pivot to a new feature or even a whole new product. If your hypothesis was wrong, you discard the deliverables from the last iteration and start another lean business cycle.

If you are an early stage startup, then what you do is build just in time. You probably shouldn’t be writing much software based on an untested idea. Start marketing what you want to build and see if there’s even a market for it that you can find and target with your budget. If you get a bunch of hits to your landing page and a bunch of form fills with people requesting information, THEN you spend time and effort on code building your product.

In short, the point of agile is to help the product development and engineering teams work together to find a product market fit. Like Henry Ford said, “If I had asked people what they wanted, they would have said faster horses.” Of course you don’t ask people anything. You try to sell them and see if they click on “buy.” This is the core of agile and the lean methodology – quickly testing whether customers will click “buy” based on your new product, new feature, etc.

Holding scrum meetings and cramming 14 hour days is not agile. Agile is about meshing the software development lifecycle into the lean startup methodology. The point of agile is precisely to never ever invest time into building the wrong thing beyond a very crude minimum viable product. If you find yourself delivering tons of unused but well-polished products or features then your implementation of agile is incorrect.

Where does TDD fit in? And BDD for that matter. By the way BDD and TDD are essentially the same, the only thing that changes is how you think of describing/documenting your tests. The differences between BDD and TDD are pretty nuanced and completely insignificant within the scope of the point we’re going to make.

It’s easy to think of TDD as a pointless fad. I certainly did. Everywhere I saw TDD being taught, the tests being written were way too trivial. In addition, the scope of TDD is never explained. They talk about the “red green refactor cycle” and all this nonsense which makes it seem like TDD is about the code you’re writing right now (it’s not). It seemed like a total waste of time because clearly writing a couple of trivial, formalized tests confers no benefit with respect to just writing your code and actually running a couple of manual tests. Clicking a button and seeing if it works is a HELL of a lot faster than this:

describe(“button functionality”, function(){
  it(“should increase the song rating when clicked”, function(){
      let state = …
      let newState = …

I didn’t even finish writing a mock test but surely you can see that just clicking the button is faster than writing all that. So why practice TDD?

For SECURITY. Your test repository is essentially an automated checklist that ensures that whenever you release a new half-baked feature to test a business assumption, you don’t break your current working app and make it unusable to your current customers. A broken app leaks users faster than internet explorer leaks memory. Having even a few hours where your app is not usable can mean your company committed accidental suicide.

So THAT’s the point of TDD/BDD. It has nothing to do with improving the code you’re writing at that time (the code your tests relate to), but it’s a SYSTEM that allows you to very effortlessly have a relatively strong gauge of whether your new features are going to break any existing code or not. You know, because we are engineers. We don’t do things like create an excel spreadsheet of QA tests (click this button make sure it does x, click that button make sure it does y, etc) and then hope that someone goes over that checklist right before every new feature release. That’s what dinosaurs do. We think in terms of systems, and TDD is a system that when enforced, is a huge help in preventing your developers from breaking your app and killing the company. TDD removes reliance on willpower and removes the mental bandwidth consumption required to have actual checklists that are enforced by someone before each release. Not to mention automated tests are faster than manually going through a QA checklist.

TDD is an integral aspect of your business because you don’t want to assume that you will fail at your business. You want to assume that your next idea will probably fail, but we all embark on business thinking that eventually we will arrive at product market fit. With this in mind, it is a monumental mistake to not practice TDD, because this is the tool that will help you manage the complexity of your ever growing application. As a code base grows, the ROI on testing grows simply because of the time it saves and the risks it helps mitigate. One could argue that you cannot run a lean business without TDD. Sooner or later, the complexity of your application will be such that you will not be able to be agile any more. Implementing new features will take too much time and too much testing. By embracing TDD from the beginning, you make an investment into reducing the risk and overhead of working in an agile way. Companies that fail to do this may find themselves incur a level of technical debt that kills their product.

Specifics about the implementation of TDD is a subject better left to those with experience in companies the size of Amazon, but suffice it to say that simply writing tests for your code is not a silver bullet. Without a plan, TDD will likely fail to avoid that technical debt which was previously discussed. The scope and implementation of TDD is unique to every team and company, and it should definitely be implemented with the specific goal to allow the business to conduct market experiments, learn about their market, and iterate towards a better product while reducing the risk of breaking their application. The effort needs to be guided by something more than just “lets write some tests.” So, should we treat TDD first as a framework and then as a methodology? Descriptive first, then prescriptive? It’s an awful thing when a developer blindly applies a methodology because it’s the latest thing (silver bullet). I think the descriptive aspects of agile are largely ignored, so it’s treated as methodology foremost, and agile without a dose of reality can be worse than no agile at all.

As complexity of your application increases, tests can assist in refactoring and making the code base more robust. That is the REAL purpose of red/green/refactor. Again, it is not about the code you are writing the test for, but about old tests going red when you make new changes. I would add one extra step…think. The cycle should be called the “think-red-green-refactor” cycle.

Finally one last consideration with agile, lean and TDD is that it is impossible to completely eliminate the risks of agile. Clearly, although agile has its risks, it’s still way better than deciding your product’s direction based on focus groups (or worse, the opinion of execs). The larger your company, though, the greater the risks agile incurs. TDD cannot mitigate all those risks because it can rarely catch things such as memory leaks, security issues, and so forth. Thus, your application can still be awful and your company can still tragically succumb due to tech debt even if all your tests are green.

— By Victor Moreno and Randy Ferrer