Jim Lynch Codes
  • Blog
  • About Jim

Writings about one coder's stories & experiences.

Gherkin - Taking Unit Tests to the Next Level

6/25/2016

0 Comments

 
Picture
So I'm almost finished reading this book, BDD in Action, by John Ferguson Smart, and I think it is really a fantastic book. Despite the wacky, ugly-looking cover, this is a super-awesome software development book that pretty much revolutionized the way I think about unit testing- and I think a LOT about unit testing so this must be a pretty big deal. I would highly recommend this book to anyone trying to wrap their head around behavior driven development, but in this post I'm going to reveal the crux of BDD- spoiler alert!


The Crux of BDD is... Gherkin!

What an awful name for a programming language, "Gherkin". After looking into where the heck this name comes from, it seems to be a type of pickled cucumber. Ok then... Anyway, for our purposes Gherkin refers to a programming language. It is code that literally looks like English. It describes the features of your application, the acceptance criteria, and how it should work. 

Tests for the Whole Team!

The problem with unit tests is that it takes a deep understanding of 1) the programming language the app is written in, 2) unit testing in general, and more specifically for the current app's language / framework, and 3) at least a basic understanding of the codebase, how the application works, and what the current component is supposed to do. Even when you have all that background knowledge, wading through thousands of lines of unit testing code doesn't normally make for a fun birthday party. This lack of team understanding leads to a fuzzy image of what unit tests are and how they are really helping the project in the eyes of everyone who isn't a programmer. Gherkin brings unit testing back down to their level. It gives them "executable acceptance tests" that they can understand without being bogged down by a bunch of [insert your favorite programming language here] code (and even for the programmers, reading the gherkin can be a refreshing way to get a high-level idea of a what certain of units tests are doing). Take a look at the example of some gherkin code below (yes, it is actually code!):  
Feature: Some terse yet descriptive text of what is desired
  In order to realize a named business value
  As an explicit system actor
  I want to gain some beneficial outcome which furthers the goal

  Scenario: Some determinable business situation
    Given some precondition
      And some other precondition
     When some action by the actor
      And some other action
      And yet another action
     Then some testable outcome is achieved
      And something else we can check happens too

  Scenario: A different situation
      ...

Single Source of Truth

Let me tell you a story about a way of developing that didn't work so well for me. I, the developer, wanted to write unit tests so I told everyone else on my team how great they are and how it'll lead to perfect code all the time being written super speedily (ok, maybe I'm promising a little too much hehe). The PM's said, "ok, sounds great!". Then we had the idea of taking the description from the unit tests and listing them in a google spreadsheet. Non-programmers are like that; they don't want to have to checkout your project from git and go digging through all your directories and code files just to see the "planning" stuff. They just want a spreadsheet, nice and clean, with everything you need laid out right there in front of you. Sure. I would like that too. But the problem is that immediately once you begin working stuff changes. Things become out of sync. You don't know what's done and what's not done, what things have been added to the spreadsheet (or the unit tests) and what things have been removed. It becomes a mess, and it may at some point become so unmanageable and wasting so much of everyone's time that the team just says, "Screw unit testing altogether". I wish I could magically appear in the room of every team going through these issues and be like, "guys, WAIT! There is a better way!". When the code directly generates your documentation and your documentation is your code then you are never scrambling to keep everything in sync.

Living Documentation

If you are a lead developer, you might report to a technology director, a CTO, or even a CEO. Periodically, they will want to know how the project is progressing. I like to refer to this a the proverbial, "So, where are we at?" question. I've had trouble answering this in the past before. Often, I'm preoccupied with whatever issues are on my mind at the moment so I'll go into that or start talking about the last thing I was working on, but this is usually not the type of answer the CEO is looking for. He normally wants you to spare him the details and cut to the chase- just the facts, and at a very high-level (but be prepared to answer questions about specifics if he asks). what if you could just give that senior manager a snapshot of the entire project? Imagine telling the CEO of your company that if he wants to know the project status he should go read through the units tests of the project (Lol! I highly doubt that will go over well!). BUT, What if you could, right through the command line, run your whole suite of easily readable, high level unit tests, and then generate a report describing each one and showing which ones are passing and which are failing- automatically. Well, with pretty much all the runners that handle Gherkin this is really is a thing! In BDD in Action, Smart talks a whole lot about these reports. He calls them "living documentation" because they are generated by the code. You don't need to "write" these reports, you just run a command and they are there. They grow alongside your codebase and evolve with it. Indeed, the reports are necessarily a reflection of current codebase. Even better than printed reports, you can set up the reports on an internal network so that management can just check out the reports at any time by visiting a url instead of bothering you (and you can use html2pdf if you do happen to want to print them out). It can also be immensely helpful to the "Business as Usual" team (ie. the people who take over once your done coding and move on to your next big project) to be able to have these easily readable tests as a way of gently and easily getting familiar with the codebase. 

A Focus on Business Value

Unit tests in the traditional sense are concerns with the functions of your program. Let's hold everything else constant (by mocking it or using spyOn), and then let's check that this one function is working as expected. This is fine, and Smart calls this low level specifications. You still have these in a BDD project. The difference is that in BDD you also have high level specifications, and these are written in Gherkin. It's the high level specifications that really drive the project, that let you know when you're done, and that help prove that you are indeed building the right software. 

Given..., When..., Then... Structure

Although Gherkin looks like just regular English, there are some syntax rules to it. When defining a Gherkin Scenario, you want to specify three things: given, when, and then. The given part is the setup for your unit test. It's the beforeEach where you get ahold of your instances. Then you have the when which describes some action that I'm taking that should trigger an event in the application to happen. The then part describes this thing that should happen in response to the action of the when statement. Inside the then is where you would normally do your assertions. But what do I mean by "inside the then"? Well, each one of these lines of Gherkin is mapped to a function in your normal coding language called a step definition.  
For example, your Gherkin might look like this:
Scenario: wrote my first scenario
    Given a variable set to 1
    ....
And the corresponding step function might look like this:
this.Given(/^a variable set to (\d+)$/, function(number, next) {
                this.givenNumber = parseInt(number);
                next();
});

Now hopefully you can see how we can have these very high level, easy to understand Gherkin tests while still allowing them to get deep into the nitty gritty parts of the code and truly test the codebase the way unit testing always has. I think most unit tests already follow the given, when, then pattern in some form. They don't explicitly use those words, and they are usually all thrown into a single method, but it shouldn't be too difficult to see how your unit tests can fit into this pattern. 

I'm Sold. How Do I Start?

If you're using JavaScript like I am,  Cucumber.js is the de-facto Gherkin runner. I've written a short Adding Cucumber.JS to an Angular 1.X Project. If you have other questions leave a comment, and I'll try to help! :)
0 Comments

Your comment will be posted after it is approved.


Leave a Reply.

    ​Author

    Picture
    The posts on this site are written and maintained by Jim Lynch. About Jim...
    Follow @JimLynchCodes
    Follow @JimLynchCodes

    Want FREE access to
    my daily stock tips 
    ​newsletters??
    Sign up here:

    - Triple Gainers
    - Rippers N' Dippers
    - Growingest Growers
    ​

    Categories

    All
    Actionscript 3
    Angular
    AngularJS
    Automated Testing
    AWS Lambda
    Behavior Driven Development
    Blogging
    Business Building
    C#
    C / C++
    ClojureScript / Clojure
    Coding
    Community Service
    CS Philosophy
    Css / Scss
    Dev Ops
    Firebase
    Fitness
    Flash
    Front End
    Functional Programming
    Git
    Go Lang
    Haskell
    Illustrations
    Java
    Javascript
    Lean
    Life
    Linux
    Logic Pro
    Music
    Node.js
    Planning
    Productivity
    Professionalism
    Python
    React
    Redux / Ngrx
    Refactoring
    Reusable Components
    Rust
    Security
    Serverless
    Shell Scripting
    Swift
    Test Driven Development
    Things
    TypeScript
    Useful Sites
    Useful Tools
    Video
    Website Development
    WebStorm
    Writing

    Archives

    February 2021
    January 2021
    October 2020
    September 2020
    May 2020
    April 2020
    February 2020
    January 2020
    December 2019
    October 2019
    September 2019
    August 2019
    July 2019
    June 2019
    May 2019
    April 2019
    March 2019
    February 2019
    January 2019
    December 2018
    November 2018
    October 2018
    September 2018
    August 2018
    June 2018
    May 2018
    April 2018
    March 2018
    February 2018
    January 2018
    December 2017
    November 2017
    October 2017
    September 2017
    August 2017
    July 2017
    May 2017
    April 2017
    March 2017
    February 2017
    January 2017
    December 2016
    November 2016
    October 2016
    September 2016
    August 2016
    July 2016
    June 2016
    May 2016
    April 2016
    March 2016
    February 2016
    January 2016
    December 2015
    November 2015
    October 2015

    RSS Feed

  • Blog
  • About Jim
JimLynchCodes © 2021