Well, I just experienced that last month, we were chatting with Dallas and after a discussion about our cucumber features I said to him “So cucumber made our scrum better, how about that?” so he told me to write about that and I think that is actually an interesting experience to share.
We started using agile practices with our team at the very beginning of our project. Very soon we started using cucumber (first time for me), because our team used it before in Ruby and they were happy with it. And there is a JS version for it. Oh yes it is, and it works pretty well. Read more here.
But… why cucumber?
Well, first off it’s convenient for executives so you can easily start using it, because they can actually understand what’s going on without a deep technical/specific knowledge, and they can see better the things the team had done with a quick look. And because of that, now communication with executives is better, and you can practice a better scrum, which can have a great impact for programmers and for the final product. And that’s a fact that everyone who worked with agile practices knows. Of course you can find a better explanation about cucumber itself by looking their homepage.
It was a great decision for us.
Other tools and practices?
Well this article is not a pro scrum nor a pro cucumber article. I think they are great, but is not what I want to talk about in this post. Also, this experience perse is nothing new, I just found interesting to point out how we saw it. So what I really want to share is this particular experience, in which cucumber, in combination with those other practices and tools actually made our scrum, better.
We already made a lot of improvements to our agile framework.
Like for example we recently started to work with one dashboard per team instead of one per project like we did before (it sounds dumb to me now I mention that, but you can just work on one prioritized list at a time… otherwise priorities lose sense, but is a common mistake that some people, to think that they are doing better because now developers can work on a lot of stuff but it’s wrong, because they are now confused wasting lots of time with context switch tasks).
Also we changed the way we create our stories to be those who strictly add business value to our application (before this, what we usually do was to create technical chores as user stories with points, another common mistake that leads to finish sprints without any real business value to the end user… which defeats the whole purpose of scrum, dummy mistake).
But recently we discovered a new issue on our development process: **shared features. And that’s what I want to talk about.
Ok, but technically speaking, how it happened?
Well we experienced it with the authentication/authorization feature -gherkin speaking- (which is maybe the better example because of how scrum create user stories for many people, based on roles and creating the “walking skeleton” from that point of view).
So the User Stories usually says something like “As a user/admin/whatever I want to do something”, all right? But anyway the common thing is to create one story for that. But it’s actually mixed: authentication, authorization, and the particular “something” for that story.
At first, we were doing special cucumber scenarios on each cucumber feature to test roles, token expiration, and so on (they have different messages, HTTP statuses, etc). There was no direct functionality related to it, as I said, it’s a cross service shared functionality. An aspect of the user story. Take this feature for item creation as an example (simplified):
Given a valid access tokenWhen a new item creation request is receivedThen create a new item on the listGiven an invalid access tokenWhen a new item creation request is receivedThen throw an unauthorized errorGiven an expired access tokenWhen a new item creation request is receivedThen throw an expired token error
As you can see in this example feature, there is one different scenario per authorization scenario on each business feature.
It turns out that when we created the first feature for the first user story, we just made an inline authentication and authorization source code, which is the common path to follow when practicing a TDD/BDD approach.
On the second feature, on the final refactor step, and with the help of some source code quality check tool like bithound or code climate detecting code duplicates afterwards on our commits, we moved that logic into a common space with some common design techniques for reusability. In this particular node case it was just a separate file with the common authentication/authorization function.
Later, we split up our service into many services, so to different repositories… and I was actually writing the source code of a specific integration chore to provide authorization/authentication to the first particular brand new service, and again because TDD/BDD, I quickly realized that I needed to create a superfluous unrelated cucumber feature to test that. Let’s say the item creation feature that I shown previously.
Well. That was the signal. I realized that having the same cucumber scenario over and over on several features implies lots of cucumber steps (test related source code) actually testing the same portion of code. If you use istanbul or some other test coverage tool like I do, you will probably understand what I’m talking about. The same branches are being tested twice or N-times being N the feature quantity in which you actually remember to test that.
So when the “chore” was completed it was obvious that, if we had a particular special feature for it, let’s say an access token/authorization feature (which implies a user story with points), we can test more scenarios and save scenarios for other business features. For example, in this case… using an expired token, or a wrong one, or no token at all, those scenarios can now be tested just in one feature for it, and on every other feature it will be implied with just two trivial scenarios that just test that the function is present on that particular feature (that the branch exist on that particular service, and I said two are needed because just one could throw a false positive).
So our new business feature like item creation became something like this
Given a valid access tokenWhen a new item creation request is receivedThen create a new item on the listGiven a invalid access tokenWhen a new item creation request is receivedThen throw an unauthorized error
And we created another feature for the authorization and authentication like this one
Given a valid access tokenWhen a generic message is receivedThen respond okGiven a invalid access tokenWhen a generic message is receivedThen throw an unauthorized errorGiven a expired access tokenWhen a generic message is receivedThen throw an unauthorized errorGiven a absent access tokenWhen a generic message is receivedThen throw an unauthorized errorGiven an incomplete access tokenWhen a generic message is receivedThen throw an unauthorized error with a custom message
In short terms, you need a user story for this kind of shared feature.
Now you may think “Ey well, don’t try to change the business (user stories) from the source code, it’s just better to test what the business says, don’t touch the user stories and if you have to write more source code, well just write it and shut up”. And that’s ok. But I don’t want to change the business. I just think that there is a better model to approach it. It saves work, increasing productivity (not writing unnecessary steps that tests the code already tested) and increasing also the final product quality (writing scenarios that may came out by getting deep into the newly created feature for the shared feature like in this case the custom error message on a incomplete access token).
Also we realized that the authentication actually has a business value by itself. Now our API is more secure. So we definitely changed that chore into a user story with points instead.
This is just one more concrete example on how cucumber act as a bridge between the technical (source code) aspect and the business aspect (or the user story), and this is done in two ways, not just one, and I mean not just to make it more understandable for non-technical people but also showing the business better to the technical people so now developers can improve their workflow to be smoother. But you need to use the right tools and practices.