TDD vs. BDD

So, I had a slightly longer break than expected. Sorry about that, folks. As promised previously, today we’re going to talk about Test-Driven Development, Behavior-Driven Development, and why I think of them as fundamentally different.

Okay, so how are they different?

Some folks might say that it’s all down to the tools used. While there are definitely different tools that are tailored for either of these methodologies, you don’t have to use them.

Some folks might say that there’s no difference, it’s all test-first development. I can understand that point of view. Whether you’re practicing TDD or BDD, if you’re doing it right and doing yourself all the favors possible, you’re totally writing your tests before you write the code to make those tests pass. That’s not the big difference to me, though.

Before I can really tell you why I think they’re different things, we should probably talk about what they are.

Okay, so what are they?

As mentioned just like half an inch up, TDD and BDD are both testing methodologies that fall under the “test-first development” umbrella: you write tests, you watch them fail, you write code, and you watch the tests pass.

In Test-Driven Development, you write tests that ensure that your code behaves the way that you expect it to behave.

In Behavior-Driven Development, on the other hand, you write tests that ensure that your code behaves the way that you expect it to behave.

It sounds like I just said that they’re the same thing. That’s not at all what I said, but I very much used the exact same pile of words to describe both methodologies.

The difference between the two is …

All about perspective

When you write a test, you do so from a specific point of view, and this is what I consider to be the fundamental difference between TDD and BDD.

I AM THE MACHINE

In TDD, it’s most often the case that one writes tests from a point of view within the code that’s under test. In some languages, these tests are even written in-line within the code in question.

Be it for the unit tests that test the code at a low-level or the integration/e2e tests that come at the problem from a high level, the point of view is basically the machine on which the code runs, so it knows all about the details of the code.

This is a perfecly valid viewpoint for testing code, and I’ve done plenty of good ol’ unit testing in my day, but it’s not really my preference.

As a User …

In BDD, on the other hand, one most often writes tests from the point of view of the consumer of the code under test. Rather than low-level and high-level tests, we think about test scopes in terms of inside and outside.

It’s a bit of a misnomer, but inside tests are about testing things out from a point of view that is inside the system, but not inside the code under test. That generally means that your tests are from the point of view of a developer that wants to use the module that you’re testing, so you describe the public API of that module and otherwise treat it as a black box. If at all possible, you avoid writing your tests in such a way that your point of view includes knowing about the actual code.

Outside tests are much better named than inside tests, in so far as your point of view is generally that of a user of the system. For a web app, that’s usually a person with a browser. For a REST API, we’re talking about a consumer client. As with inside testing, though, you’re treating the system as a black box aside from the actions that you know you’re allowed to do from that point of view.

So, why is BDD better?

It’s not definitely the case that BDD is a better methodology. I prefer it to classical TDD myself, but that’s not the same as it being measurably better.

That said, a bit part of my bias in favor of BDD is that it forces me to think about how folks are going to use the things that I create. I’m the sort of person that values solitude, and one of the side-effects of this is that I sometimes have trouble giving proper consideration to others. It’s something that I’ve been working on for a long time.

To that end, I can publish all of the libraries and apps that I want, and I’ll definitely know how to use them regardless of how convoluted they are to use. However, assuming the role of a consumer before I start writing that code helps me to more readily consider the user experience for the things that I create, and that has helped me immensely.

Specifically with outside tests, another advantage that I greatly enjoy is that with specific tooling, I can present my outside test to users as a form of documentation. Well, provided that I write good feature descriptions, anyways.

Til Next Time

I’m going to try to actually stay on schedule for a while. I have a few possible blockers, so I may not be posting on Tuesdays specifically for a while, but I’m shooting for at least weekly.

So with undue confidence, I’ll go ahead and say that I’ll see you next week to talk a bit more about inside testing, outside testing, and specifically how I go about doing them.

 Date: May 2, 2023
 Tags:  bdd philosophy tdd testing

Previous
⏪ Unplanned Break

Next
Pleasant Workflows ⏩