More details soon..
They say you can’t get over a problem until you admit you have one..
Microsoft finally give away a free anti-virus application
Don’t be so disgusting, it’s obviously a cucumber.
Or Cucumber with a capital C, perhaps, which was frequently long, hard and red (steady!) until our shiny new testing regime was unveiled!
As part of our commitment to use Cucumber more effectively, here are a few of the things I have learned about its use, and if you learn them too (from me) you will enjoy using Cucumber just as much as this guy enjoys being brutally murdered:
Background, the new GivenScenario
Remember GivenScenario? If you don’t, I don’t blame you. It died in infancy, and in fact was boxed and buried before I even had the chance to use it.
The idea was that you could define some sort of ‘set up’ scenarios that saved you from having the same code repeated all over your feature spec. There were a number of problems with this solution though, as you ended up with scenarios that had no value other than as leg-ups for other scenarios, and it could get pretty confusing if your GivenScenario had a GivenScenario itself, and so many other reasons. It makes you wonder why they ever thought it was a good idea. IDIOTS.
So anyway, you write ugly, repetitive features like this:
Scenario: view preferences page Given I am logged into cas as "Peter" "Portal" with an username of "00700001" And I am a Business School student And I am enrolled on a course And there are campuses And I am on the preferences page Scenario: should show user personal details Given I am logged into cas as "Peter" "Portal" with an username of "00700001" And I am a Business School student And I am enrolled on a course And there are campuses Then I should see "Peter Portal" And I should see "firstname.lastname@example.org"
There is a newer, and better way to do this though. Introducing Background, which you can use in pretty much the exact same way, but it doesn’t count as a scenario itself. Joy.
Background: Given I am logged into cas as "Peter" "Portal" with an username of "00700001" And I am a Business School student And I am enrolled on a course And there are campuses And I am on the preferences page Scenario: view preferences page Then I should see "Your Profile and Preferences" Scenario: should show user personal details Then I should see "Peter Portal" And I should see "email@example.com"
Lovely (this gets much more lovely than you can see here, as there are a lot of scenarios with the same background).
As I was writing some particularly awkward Cucumber steps involving assigning something to something else and then assigning it to something else (see, pretty confusing), and having been told assigning stuff was much harder than it actually turned out to be, I was really struggling to figure out what was going on.
I ended up putting in a load of print statements to see what my variables were doing.
There is a better way though. I was pointed to this article, which describes how you can use
breakpoint in Cucumber steps.
However, you shouldn’t do this, because
breakpoint is deprecated, and it’s now called
debugger. You can put this in anywhere and when you run the test you get an interactive prompt and you can inspect any variable you wish (and probably even set things if you’re trying something out). The most convenient way to do it, as described in the article, is to put it in a step by itself:
Then /^I debug$/ do debugger 0 end
That way you can simply drop in the step whenever you want to know what’s happening:
Scenario: list users Given I am logged into cas as "Peter" "Portal" with an username of "00700001" And I am on the glamlife users index page And I debug Then I should see "Glamlife Users"
When you’re finished with the debugger, just press Ctrl+D, and Cucumber will continue on its merry green way.
You can even put it in a Background and debug all your scenarios at once if you really want to!
Honourable mention goes to
save_and_open_page, which will open the page in a browser so you can see visually what’s wrong with it, instead of having to interpret the HTML, see the Technical Pickles blog for more on this.
As usual there’s a Railscast covering much of this stuff, and more (there’s some particularly good stuff in there for people with many similar features with just a couple of variables), and for anyone who is just here to look at the pictures, there’s also a good one with an introduction to Cucumber.
Don’t be an idiot
All this won’t help you though, like it didn’t help me, if you miss something obvious like the fact that if your ‘visit’ line doesn’t come after your other Givens, you data won’t be there no matter how much you debug. 🙁
This week I have been experimenting with Liquid.
Not an excuse for boozing at work, but a method of allowing content editors to incorporate dynamic content without having access to all the wonderful and dangerous things that Ruby allows.
In short, you can use tags which look like to output variables or to do simple computations. If you’re interested (and who wouldn’t be?), you can read more about Liquid here.
The object of this investigation was to allow content editors to include polls in their content that users could vote on. Polls are a feature that we’ve been thinking about adding to Glamlife for a while, and it was decided that giving editors the option to add them into Glamlife’s ‘chunks’ would be the ideal way, to give them as much flexibility as possible.
So my first task was to try and dig up as much information about Liquid as I could find. As is so often the case with these cutting-edge technologies, there isn’t much out there. The Liquid developers’ wiki was useful, but not exactly comprehensive. I was also able to find a few blog posts about it, for example this one about custom tags, and this overview of Liquid’s features.
If a picture is worth a thousand words, how much is a video worth? I found that the most useful resource by far was Ryan Bates’s ‘Railscast’ video tutorial on using Liquid. After watching this and having a little play with it in the Rails console environment, I felt pretty good about Liquid and set about trying to shoehorn the poll form into it.
As many of you will be aware, however, life has a nasty habit of crushing your dreams just when you think they might be coming to fruition. Imagine my despair, then, when I found that the Rails helper methods (which are required for the form) are unavailable in the lib files which you are required to code your custom tags in. As yet, with my relatively limited knowledge of Rails, and despite watching another Railscast video, I have been unable to solve this problem.
An interim solution will be to simply hard-code the form into a view. This is inflexible, and will only show the latest poll created, but it will at least get the feature out into the wild and satisfy the clamour for exciting new features. Keep your eyes peeled on Glamlife (if you have access to it!) to see if we have more success with this!
UPDATE Theres seems to be some work on creating a repository of common scenarios and stories at the aptly named Cucumber Stories
Why is this interesting?
Well, the theory goes that once the feature requirements are written in the featurename.feature files then the coders write steps that correspond in featurename_steps.rb files. This is where code that actually does the things being described lives. By defining features in this way the coders are clear what exactly is required and the time consuming back and forth working out what people mean is reduced. By writing down what is meant it gives people a solid starting point. If the stories need to change then they can, but this aspect of the project is a clear way to get clarity from the clients on what they want.
Thats’s the theory.
To get started you can see that Craig Has some instructions and background on how to get it up and running.
And once you’ve done those things you’ll be itching to get cracking and write some features and scenarios. Craig also helps us out here
What it feels like to write them
I’ve been doing this for a couple of days now and to be honest am still struggling a little about how much detail I need to be going in to in the scenarios. So i decided to describe the behaviour in broad terms. If that is acceptable to the coders in the team that is fine; if they think that more detail is needed then they can define that or any other member of the team.
Here is an example of what I’m talking about.
Feature: Provide News
In order that news is relevant and timely
As an editor
I want ability to add news
Scenario: Add person to system
Given They are allowed
And they have been trained
When an editor is added
Then they have ability to add, create and edit news
In this example, the business value is the provide news from my area. The role is defined as an editor and the action is ability to add news.
So, I then go into a scenario which is to detail how the feature actually will work. In the example we describe the behaviour needed to add a person to the system. Given is a reserved word which sets the context. In this exammple it assumes that the user only arrives at this step once approved. Note that it doesn’t specify how that is done, just that it should have been done (We will come to that in another post.)
And is also a reserved word that allows us to add the the behaviours. IN the example above I am requiring that have been trained. Again, how we verify this is for elsewhere; all we need here is that it has taken place. When those steps have taken place we define that the next step is to add the editor, and to verify that has taken place we use the reserved word Then to check that the previous step has been completed.
The next stage
This is the first part of the process. The really clever bit is that steps are written in corresponding step files to make the behaviours we defined here a reality. Steps are beyond the scope of this article, but there are some good examples and explanations
I’ll let you know how we get on with this method.