In the last chapter, you understood that writing tests is important in development. You don't wanna break your code!
Tests can also serve a larger function across both your development team and the rest of your company if you choose to follow a philosophy called BDD (behavior-driven development).
Imagine you're a developer, and you receive a specific request from a product manager, marketer, cofounder, or anyone else in your company. You need a way to translate their requested feature into code. 💬🔜💻
Thinking about how you'll design your tests will help you design your code afterwards.
BDD: Behavior Driven Development
Behavior-driven development requires a goal. Let's use a nice sailing metaphor. Before you start sailing, it's a good idea to have an idea of where you want to go, right?
The same is true with code. Imagine you're the ship, and your new feature is the X:
Behavior-driven development will help you identify exactly where your code should take you.
Step 1: Collaborate and define
Someone in your company has requested the change you're supposed to make. Sit with them and spec out their vision of the feature and confirm there's a real need behind the proposed change.
Therefore, the first step in practicing behavior-driven development is to collaborate with the other stakeholders in the feature you're building.
Through this collaboration with a feature requester, you can evaluate whether the change is really necessary and if there's a simpler way to go about it than what they proposed.
Defining things to test
Let's say you work for an online publication (think Mashable, Buzzfeed, etc), and a product manager wants you to add a commenting functionality, so people can leave their opinions on articles. Those are the only instructions you have.
These instructions may be enough to get started, but once you start coding, you'll realize there's much to clarify about the commenting feature's behavior.
You might realize you don't know:
how long each comment can be.
what should happen if a comment includes profanity.
what happens if a user leaves a blank comment.
if anyone can post comments or only users with accounts.
etc.
These are questions that are great to answer collectively with the team which with you're building your project.
To make things even easier when you're clearing up these questions with other project stakeholders, use the BDD syntax below as part of your discussions.
Behavior driven development syntax
BDD often includes human-friendly words like Given, And, When, and Then to describe the circumstances you're dealing with.
You describe a theoretical situation, any other circumstances, and what should happen by using these words (Given, And, When, Then).
For example:
Given a user leaves a comment
When the comment is over 1,000 characters
Then the comment should not save
And the user should see an error message
You may be wondering, "Where's the code?" There is none yet! Some code testing frameworks even allow you to use those key words (given, and, when, then) in your code tests, making them very readable.
Practicing behavior-driven examples
We'll run through some examples together to see how behavior driven development practices might play out in different scenarios. Seeing these other scenarios will allow you to better internalize the syntax and nature of writing behavior-driven specs.
Localization
Websites often have multiple versions available for people in different countries (who therefore probably speak different languages). Often, a user will see the appropriate version of the website based on the country from which they're accessing the page. 🌍
For example, a user in Spain should see the homepage of the website in Spanish, right? It would be a little silly to serve people in Spain the Chinese version of the website. Even though plenty of people in Spain probably speak Chinese, it'd be more probable that they'd speak Spanish.
Using the keywords given, when, and then (plus and if necessary), here's how you might write out these different language scenarios.
Given a user is in Spain
When they visit the homepage
Then they should see the Spanish version of the homepage
You could write the same types of specs for French users:
Given a user is in France
When they visit the homepage
Then they should see the French version of the homepage
You might also think to include negative situations in here, for example:
Given a user is in Spain
When they visit the homepage
Then they should not see the French version of the homepage
By detailing scenarios like this, you make it clear which scenarios you'll need to test once you actually start writing your code tests.
Tic tac toe
Let's say you have an online video game that allows two people to play tic tac toe against one another. ❌⭕️
The squares are laid out as follows:
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 |
You don't want two players to be able to be on multiple squares at the same time, since in tic tac toe, each square can only hold one player.
You could write a test to confirm that a player should not be able to take a square once it has been taken by a competitor. Here's what that behavior might look like using concrete player details.
Given player 1 is on square 3
When player 2 attempts to take square 3
Then player 2 should receive an error
And they should not be able to take square 3
Now that you've seen a few different examples about how to write out behavior-driven specifications, you'll see in the next chapter how to turn them into test-driven development.