Posts Tagged bdd

BDD: What if we do NOT focus on ‘System’ behavior?

This is a way many people and literature talk about Behavior-Driven Development (BDD): “it encourages teams to use conversation and concrete examples to formalize a shared understanding of how the application should behave.” (wikipedia)

Focus on the application‘s behavior leads to user stories that start like this:

As a system…

Do we write code for the system?
Are we serving the system?
Is the system a stakeholder?

Continuing the story…

I want to…

Oh, so the system tells us what it wants? Are we already there?

Most software developers have a strong tendency to jump too quickly into problem-solving from a technical perspective, failing to see the problems the humans need solving.

Say we’re using state-of-the-art technology, implemented with the most amazing code, on the most advanced platforms, using valuable resources, such as time, attention, and money; it it worth it if humans’ lives aren’t any better?

Many times, the problem that needs solving is a process problem. Many times, it’s a people problem. Often times, social and/or cultural problems also get in the mix. Here’s an example of the latter:

A socio-cultural problem

In the mid 2000s, I met a group of developers in Redmond who had just come back from Sao Paulo, Brazil.

They had been working on a pilot project to improve the quality of public transportation, implementing a tracking system for the buses, so people could know with more accuracy when their next ride would show up.

The system was working great, except for this one bus that kept “disappearing” from the system for at least 30 minutes everyday. Puzzled, they developers were looking at the data, code, and everything in between.

The cause of the problem?

The bus driver found out how the system worked and figured out he could use its sim card in his own phone to make long distance calls to his family, who lived in the north part of the country. That was a time when long distance calls were still very expensive.

Most local developers would have caught that possibility that the foreign ones didn’t consider. The system was behaving according to spec. But the humans…

Maybe the problem that needs solving is dealing with some people’s natural behavior that may put them far from a bigger goal.

Maybe we’re trying to develop a solution that will acknowledge people’s natural behavior and make sure the desired outcome is achieved.

Or maybe the solution can help change people’s behavior gradually.

Here’s an example. In 2017, I started riding sport bikes (motorcycles, that is) at race tracks. It didn’t take much to realize that it can be an expensive sport. Doing my research and asking other riders how much they spend in their riding season, some would say “I don’t even wanna know!” Asking how often they ride, some would answer “whenever money permits“.

Well, I do want to know; if I know and understand where the money goes, I can identify ways to optimize my expenses and get to ride more!

Here’s one of the user stories I wrote at the time to capture that need (which I implemented in www.BeyondTheTrack.net and have been using all these years):

Estimating Costs

In order to plan out a track day calendar within my budget
As a rider
I want to indicate estimated costs for each track day

Scenarios for the story looked something like this:

Given track days I plan on attending
When I enter their estimated costs
Then I can see the budget I will need for my riding season

By facilitating a behavior of setting proper budget for goals that are important to me, my life is better. My behavior. Not the system’s behavior.

How did that work out for me in that specific case?

Comparing my Year #1 in track day riding to Year #6, the number of days I rode went up by 146%, while the money I’ve spent on it went down by 78%. Value up, cost down. Win-win in my book. The chart below shows 2017 through 2022.

The closer we get to the bits and bytes, yes, specs will tend to describe what we expect from the system. But that’s NOT where I believe we should start from.

In the great books Specification by Example and Writing Great Specifications, the authors are very specific at sticking to the definition of BDD as Dan North meant it.

In this post, I’ve put my own spin on it, as this is how I’ve practiced it over the years.

In his talk about “Leadership vs Management: What it means to make a difference”, Seth Godin talks about how people think Beethoven’s 5th Symphony should sound: the way the maestro wrote it, or the way made popular by Arturo Toscanini? Interesting watch.

,

Leave a comment

Recommended Reading on Testing

I give many talks on Testing (more specifically, TDD, BDD, unit testing, etc.) and often get asked for recommended reading on the topic.

I’ll list here some of the resources I remember I’ve read. Beware that some of them I’ve read a long time ago and do not know how well they’ve aged.

I’ll focus solely on books. I know I’ve read useful blog posts in the past, but I haven’t kept track of the most relevant for me, unfortunately.

Working Effectively with Legacy Code, by Michael Feathers

Amazon link

I’ve read this book twice. The first time was shortly after it came out in 2004. It had been only a couple of years since I learned about unit tests and had already felt the pain of writing tests for legacy code. I remember the book helped me a lot through period, and many of its lessons stuck with me.

I’ve read it a 2nd time earlier this year (2022) and believe the book has aged well, and think every developer should read it at some point in their career.

“oh, but I don’t work with legacy code”. If that’s you, just know that the code you wrote this morning may already be considered “legacy”.

Agile Principles Patterns and Practices in C, by Robert C. Martin

Amazon link

This book came out in 2006, and that’s when I think I’ve read it. I remember recommending it to many developers for several years afterward.

I loved the book because it covered OOP, Design Patterns, SOLID principles, and TDD, often writing tests before refactoring code that would eventually surface as a pattern or principle.

I have not revisited this book in many years, but I know that a lot of the things I’ve learned from it have stuck with me.

The Art of Unit Testing, by Roy Osherove

Amazon link

I’ve read this book around the same time as the other two mentioned above. The Amazon link is for the 2nd edition, published in 2013, which I haven’t read (I see there’s also a 3rd edition, with samples in JavaScript).

I recall learning things about fake objects (mocks, stubs, spies), and I remember recommending this book to other developers back then. If memory serves me right, it’s a short book to read and it provides good information for those getting started into the practice.

Fifty Quick Ideas to Improve Your Tests, by Gojko Adzic and David Evans

Amazon link

This one I’ve read earlier this year and enjoyed it very much, as it validated many of the lessons I’ve learned and applied over the years, and it also gave me some new ideas to try out.

The RSpec Book: Behaviour Drien Development with RSpec, Cucumber, and Friends, by David Chelimsky, Dan North, and others

Amazon link

I’ve read this book when I moved from .NET to Ruby on Rails in 2011. I found this book as I was digging more into Rails, Cucumber, RSpec, Testing, BDD, and all that stuff, and it helped me at the time.

I am positive that things I’ve learned there were brought over when I came back to .NET years later, and I also apply it to JavaScript, TypeScript, Cypress.io, Jest, etc.

Is that all?

Those are books that first come to mind when people ask. I’m sure I’ve read others in the last 20 years, but I didn’t use to keep track of it they way I have been in the last few years, and whichever other books I’ve read didn’t stick with me.

I’ve put out several blog posts on the topic of testing, documenting my questions, confusions, learnings, etc., and will continue to do so.

I also have a list of books on the topic on my “to read” list, and I’ll write up posts in case the books deserve it. 🙂

While the books mentioned here have helped me along the way, the single most important that shaped my practice has been actually doing it!

,

Leave a comment

Book Review: The RSpec Book

I’ve just finished reading “The Rspec Book: Behaviour-Driven Development with RSpec, Cucumber, and Friends”, and I totally recommend it to anybody writing Ruby code. Being fairly new to Ruby, I had limited experience (still do) to RSpec and Cucumber, but despite plenty of literature available on the web, I was glad to find a book dedicated to this subject so I could absorb some structured information.

The RSpec Book: Behaviour Driven Development with Rspec, Cucumber, and Friends (The Facets of Ruby Series)

I like the way the book is organized and how it develops the idea of “outside-in” development; starting from writing features in Cucumber, writing “the code you wish you had”, and then going into RSpec to drive out the implementation of controllers and models.

The authors do a great job at explaining how RSpec works, and that was very useful as that had been kind of magical for me. I start to see more and more what people have been raving about regarding how Ruby is such an elegant language. The book also includes tips on how one can clean up tests by using built-in matcher, or creating custom matchers, and stuff like that.

I’m keeping this book handy so I can use it as a reference as I write my tests and look for ways to improve clarity.

, , ,

Leave a comment

Rails, Cucumber, RSpec, Testing, BDD, and all that stuff

Three years ago I blogged about my thoughts at time on the whole testing thing. I have stuck with the practices and really believe on it. I’ve tried different tools and approaches, and I keep trying different things as I go. Behavior-Driven Development (BDD) seemed like my next step, but it didn’t take me long to realize MS-Test didn’t give me what I needed in order to start to get into that practice. There wasn’t much I could do as I was stuck with it.

When C# 3.0 came out, I’ve learned how I could improve my tests using extension methods, building some sort of fluent DSL to test certain things. Eventually, I was able to migrate to xUnit, along with SubSpec, and then I was able to write tests a lot better, following the “given-when-then” style. Writing new features and certain components following that style has been great; I believe everything I wrote following that approach has a much better design and quality.

I had heard Rails developers gave a lot more importance to BDD and testability than .NET developers, so that was one of the driving factors that encouraged me to try Rails.

After getting a little more comfortable with Rails and Ruby, I started to devote more time to RSpec and Cucumber, without really understanding much what they were exactly. So far, I’m enjoying using both. I’m almost done reading the RSpec book (I’ll post a quick review once I’m done) and writing as many tests as I can, but I still have lots to learn; I’m still at that stage where I do know there must be a better way to write something, but I’m not to a point where I know how to do it.

I am writing lots of “features” formatted so that I can drop them into Cucumber .feature files, and then implementing them. I’m finally realizing some benefits of BDD that were apparent to me before. Up until recently, I was seeing BDD mostly as a way to write tests where the scenarios were described such as “given whatever, when something happens, then I should get x”. But those were described as strings surrounded by C# code, so the business value wasn’t immediately apparent.

Now, however, I’ve been sticking to this format (right off the official Cucumber site):

feature

This format makes it a lot easier to see the business value out of an atomic feature. It shows a short title for the feature, the ultimate value out of it (“in order to…”), who’s getting benefit from it (“as a…”), and what the person wants (“I want to…”). Then, it describes the different scenarios that exist for the given feature. I like the fact that there’s no specific programming language clutter mixed in with the description of the feature. 

If I’m the one writing those stories, as a developer, it forces me to be as clear and succinct with the English language as possible, so that it will make it easier for me to validate these with my clients and users; and as they get familiar with the format, they can start providing me the stories themselves.

Another advantage I’ve been noticing doing these is that by analyzing the number of steps within a given scenario I can identify whether the user experience is going to be good or not. The scenario unveils how hard it is for the user to access the feature (“user has to click this, select that, fill out the other, click this other thing, and only then get to what she needs…”), and how the user interacts with the system (what the user does, and how the application responds).

Breaking scenarios into small, concise units… doesn’t that sound similar to “breaking classes into smaller, concise classes, methods, etc.”? Putting some good thought into writing these stories can help out the developer later when actually implementing the feature.

And here’s another benefit of keeping scenarios small and concise: planning. When discussing the feature with the clients, I can get them a feel for the complexity on each scenario, and they can tell me which scenarios are must-to-have, and which ones could come at a later time. This way we can plan on which features and which specific scenarios are going to be implemented on a given iteration or release.

I’m also following the idea that “Cucumber tests cover the application’s behavior, and RSpec tests cover class’ behavior”. In other words, I write Cucumber tests to check a feature end-to-end, from the user’s point of view, and I use RSpec to test a class’ behavior.

Some people say one of the main advantages of Cucumber is that non-technical people can easily read, or even write, the tests, but some developers say “the non-technical people will never read anything anyways, so why bother?”. So far, I’m seeing the Cucumber tests as being very beneficial for myself, for the reasons listed above (like forcing me to think of the features in a cleaner and more concise way, etc.).

At the moment, I have the following workflow:

  1. Write the features and store it in Evernote (tagging everything so I can group features based on specific user roles and things like that);
  2. Review stories with the client, rewrite pieces, split features up, move scenarios around, etc;
  3. Once it feels like a given feature is a little more stable, I put it on the Kanban board in AgileZen;
  4. Pick features that are on the board, and plan them accordingly;
  5. Once I start working on a given feature, it’s just a matter of turning them into a Cucumber file, and go about implementing it.

This is not written in stone, and it’s just something I’m trying out. I have no idea whether that’d scale for large teams or whatever, but I’m being pragmatic and doing whatever it takes to be productive given what I have. It seems to be working. I’ll keep you posted. Smile

, , ,

4 Comments