Talks

Story Driven Development: The Next Generation of Rails Functional Testing

Help us caption & translate this video!

http://amara.org/v/FGkg/

GoRuCo 2008

00:00:13.759 Thank you very much for having me today! I'm delighted to be here speaking in New York, my current residence. I'm going to be talking about story-driven development, what I would call the next generation of Rails functional testing.
00:00:27.480 To get an idea of people's familiarity with these concepts, please raise your hand if you are familiar with the concept of user stories in one form or another. Okay, great! And then how many of you use RSpec right now? Wow, that number has gone way up! Finally, how many of you have actually played around with the RSpec Story Runner? A few? Okay, cool!
00:00:40.719 So, the next generation of Rails functional testing is kind of the flashy tagline, the whiz-bang title meant to get the talk accepted and entice you to show up, but this is actually really useful stuff, and I’m really excited about it. For me personally, this approach has been the biggest step forward in my development practices since I started doing Test-Driven Development (TDD). So, who am I? Well, no one really; I don’t have any books and I don’t blog enough. However, I’ve been doing Rails for about three years now and I am a member of the New York City Ruby Brigade. Currently, I work at We Play, and you will see some jerseys floating around; those are my co-workers.
00:01:12.720 We’re basically creating Facebook for the youth sports vertical—yet another Rails social network because we definitely need more of those! Now, raise your hand and keep it up if you have spent time on a project simply producing a functional specification document, collaborating with engineers and customers who all signed off on it, and you were sure this document would drive the project through and get everyone what they wanted.
00:01:59.600 Now, keep your hand up if you actively used that document throughout the course of the project to build the software it described. Interestingly enough, I only see two hands up.
00:02:12.360 So, there are problems in software development. We describe ideas on paper, but without seeing the software, no one is really sure what's needed. Our product owner or customer at We Play often says, 'I’ll know a lot better after you build it.' If it isn’t done right, then we’ll have to come back and work on it some more. But it’s quite challenging for him, in all fairness, to think about these interactions and the design of this complicated software just from that perspective.
00:02:31.120 Sometimes, it’s hard to tell when you’re done with development. There are times when developers think they are finished, but the customer hasn’t received the value they expected. Additionally, there are times when developers continue beyond the minimum requirements to implement a feature, which can be wasteful. The customer may have been satisfied with the feature earlier, but development proceeded and resulted in additional costs.
00:03:06.520 Sometimes, we code up features without asking if the customer actually wants them. Our customer might say, 'You know what, that’s good enough. Don’t bother adding the AJAX; it’s more important that we get this other feature coded, and maybe we'll come back around to add some AJAX later.'
00:03:18.540 Estimation is a significant challenge in software development right now. Personally, I’ve handled this by making rough estimates and doubling the figure just to be safe, which is typically the approach many professionals take, since it’s really hard to predict how long it’s going to take to build this application. We often run into issues ensuring the application still works as you develop it.
00:04:11.720 For example, if you tweak a before filter in application.rb, how do you ensure that you haven’t broken anything in the app? Nobody wants to go through every interaction in the app just to check that this widespread change didn’t break previously verified functionality. There was a time during the We Play launch where we received a request for a copy change to update some text related to media privacy settings, and it turned out that this functionality everyone assumed was there actually didn’t exist.
00:05:02.840 With story-driven development, you can remove ambiguity when defining requirements and establish a common vocabulary between customers and developers, facilitating better communication. You can also maintain simplicity throughout the development process, adhering to the KISS principle.
00:05:29.800 With story-driven development, getting confidence in your refactoring becomes achievable. You can build new features, fix bugs, and make changes to application.rb while being relatively confident that the application will still perform as previously verified. This method catches errors before they check in and before deployment.
00:06:06.880 One time on the We Play project, after we began this process, we added stories for our activity feeds, similar to the Facebook news feed. It turned out that those activity feed stories were among our best means to catch regressions in various functionalities because they ran all the time. This was essentially free after they were written.
00:06:52.720 To fully understand how the application works, it’s beneficial to have executable documentation. If it’s not executable, it tends to become like the specifications document many of you have worked on. It can wither away over time and can do more harm than good.
00:07:19.800 What is story-driven development? It all begins with the story format, which we will go through step by step. You start with a story title that describes the activity or functionality you wish to build. It should be brief, fitting on an index card, as this is how we track our work for the week.
00:07:50.560 The title must explain, at a suitable level, what the customer or product owner can understand about what is being asked for. For example, let’s consider an application designed to track Rails developers for a headhunter who frequently needs to hire more Rails developers.
00:08:20.960 Next, after your title, there should be a narrative. The format we prefer is ‘As a [user], I want to [do something], so that [value].’ This format helps us clarify the goal, representing both user and business value.
00:08:53.180 This framing puts us in a context to think about who will utilize this feature, encouraging our customers to consider real use cases in the actual world.
00:09:06.480 Moving on to scenarios, they require a title that describes the difference without repeating the story title. The words in the title should be high impact, avoiding redundancy. It is beneficial to include verbs; for instance, ‘Reject invalid zip codes.’ This indicates that your function is handling invalid zip codes.
00:09:26.600 The body of the scenario should include a 'given', 'when', 'then' structure, which offers context, actions, and expected outcomes. The key here is that these steps should be approachable for stakeholders, customers, developers, and testers, using straightforward language that everyone can understand.
00:10:05.760 For example, in the ‘given’ part, you simply outline the relevant context needed for the scenario. Importantly, you don’t need to provide excessive detail about unrelated processes.
00:10:22.160 The 'when' step defines the action. It is essential to represent the feature being produced, while the 'then' step outlines outcomes or assertions. For those familiar with test unit development, this resembles standard assertions.
00:10:58.080 User stories, an agile concept, serve as tools for planning and analysis, serving as prompts for later conversations regarding specific functionality. They don’t require excessive detail but need sufficient context for teams to effectively resume discussions later.
00:11:45.440 Story-driven development, on the other hand, takes this a step further. They not only facilitate design discussions upfront but ensure clear acceptance criteria. Furthermore, story-driven development embraces both agile concepts and story-driven practices, benefiting greatly from the synergy between the two.
00:12:39.680 It's crucial to describe a single case within each story. A common pitfall is using 'if' statements, especially with customers wanting to use them in their descriptions. Instead of saying, ‘If the ZIP code is longer than five digits, then reject,’ it is more effective to define two cases—a five-digit ZIP code and a six-digit case.
00:13:16.280 Instead of focusing on imperative details, stories should be declarative and unambiguous. An example of an improper approach would be describing steps too intricately, leading to unnecessary complexity... like saying: ‘Given I’m on the developer's page, when I click the add developer button, then I should see the ad developer page when I enter the first name Zed and the last name Shaw, then I should see the message that Zed was created.’ This is inefficient and painful to maintain.
00:14:15.960 Instead, I propose a cleaner approach: 'Given there is a developer Zed Shaw, when I try to add a developer named Zed Shaw, then I should receive an error stating there can be only one Zed Shaw.' This maintains clarity while testing the same critical functionality.
00:14:41.800 Implementing scenarios focuses on automation. This is where the ‘red button’ analogy comes in—what if you had a red button that informed you if your application functioned correctly? How often would you press it? The suite of scenarios essentially functions as that red button.
00:15:17.200 Our team uses the RSpec Story Runner, which consists of three components: the plain text stories, the step matchers that execute those stories, and the runner file that connects both. The RSpec Story Runner was inspired by a prior project called RBehave by Dan North, which was based on JBehave.
00:15:56.960 Everyone involved recognized the value and integration of this functionality into the RSpec ecosystem. The output resembles clean and natural syntax. We write our scenarios in plain text before creating the necessary step matchers to make them executable.
00:16:41.920 When running a scenario, if it passes, you receive favorable output. However, if it does not work due to unimplemented functionality, like a missing input field for Rails experience, it won’t execute all the steps and indicates the source of failure.
00:17:28.360 Once functionality is implemented, a previously failing scenario can pass successfully, helping visualize the development process. In the early stages of iteration, you might encounter more pending scenarios, but ideally, everything should turn green by the end.
00:17:49.520 At the conclusion of an iteration, if all scenarios pass, this indicates that your test-driven processes are delivering the desired functionality. This system encourages continuous evolution within the scenarios, reflecting shifting demands during development.
00:18:32.760 Writing new scenarios for new functionality being developed is essential, and undergoing frequent cycles of writing scenarios ensures that everything functions without bugs. Discussions surrounding scenarios can enhance customer engagement, as they allow you to iteratively verify the direction of the product.
00:19:17.800 Finding a balance between being too specific or too general with your scenarios boils down to understanding the expected axis of change for that functionality. If you know that a piece of information on the page is likely to change, you can write your tests in a flexible manner that allows for adjustments without breaking the test.
00:20:12.200 Our experiences implementing these methodologies often lead to important revelations: tests may fail revealing bugs in the application that need correction. The aim is not absolute perfection in coverage, but rather creating a dependable system that encourages iterative refinement of scenarios.
00:20:47.560 Lastly, I'd like to clarify how story-driven development fits into Agile methodologies. The team produces executable scenarios for user stories prior to any coding begins. It's vital to emphasize the collaborative nature of this effort, bridging product needs with engineering execution.
00:21:36.920 There are various resources, both online and in book form, that can offer insights. The RSpec website provides thorough installation instructions and valuable information about the topic. Dan North's insights and webat can enhance your understanding of this process. My own blog, bryan.com, will include more discussions around these topics in the future, as I've committed to increasing my writing efforts, and Mike Cohn’s book 'User Stories Applied' is a fantastic read for working with customer collaboration.
00:22:24.160 I’m now interested in answering questions—please raise your hands if you have any questions, and we’ll do our best to address them.
00:23:08.480 If there are no questions, I’d like to mention that implementing testing strategies improves performance and maintainability of product specifications, ultimately enhancing customer satisfaction and code quality.
00:23:47.560 To summarize, developing a solid testing framework involves user collaboration, precise storytelling, and an iterative approach to ensure every part of the application performs well at its intended purpose. Together, we can create a more effective workflow that benefits both developers and clients. Thank you for your attention.