Arie’s Blog

Story-based acceptance testing

November15

In my previous post I talked a bit about Behaviour Driven Development and RSpec’s beautiful syntax for writing specifications.

This week I stumbled upon acceptance testing in RSpec and a very pretty way of writing those tests.

A simple acceptance test would look like this:

Story: A user sends an invitation

The invitation page should allow users to invite friends

Scenario: Sending an invitation
Given a new unused email
When the user goes to /invite/create
And the user types 'Test' into the invite_name field
And the user types 'User' into the invite_surname field
And the user types 'someemail@email.com' into the invite_email field
And the user clicks the commit button
Then the page should contain the text 'Test User was invited'

Scenario: Sending an invitation to an already used email address
Given an already used email address someemail@email.com
When the user goes to /invite/create
And the user types 'Test' into the invite_name field
And the user types 'User' into the invite_surname field
And the user types 'someemail@email.com' into the invite_email field
And the user clicks the commit button
Then the page should contain the text 'Email already exists'

Now these tests don’t do anything by themselves, you need to run them against the application.
This is where Selenium comes in. Using RSpec’s story runner, you can feed these plain-text stories to Selenium.

Selenium will open your web application in a browser and go to URL’s, enter data, click buttons/checkboxes/radiobuttons. It’s kinda spooky to see your browser navigate to pages by itself ;)

Here’s another test that checks the login function

Story: A user logs in

Scenario: Logging in fails
Given a user with username 'Arie' and password 'test'
When the user goes to /login
And the user types 'Arie' into the login field
And the user types 'not-test' into the password field
And the user clicks the commit button
Then the page should contain the text 'Unable to login'

Scenario: Logging in successfully
Given a user with username 'Arie' and password 'test'
When the user goes to /login
And the user types 'Arie' into the login field
And the user types 'test' into the password field
And the user clicks the commit button
Then the page should contain the text 'Logged in'

For now I’m not planning on covering my entire application with tests like this. I’m just going to make a few tests that I can show to my school when I finish my internship.

Behaviour Driven Development

November8

I’m currently doing an internship as a final part of my study. Luckily I’ve been able to find a company where I can use Rails to create a new application.

One of the choices I made for the development is the use of BehaviourDrivenDevelopment (BDD), which is a variation on TestDrivenDevelopment (TDD).

Rspec is a BDD-framework for Rails. It features a beautiful way of expressing the expected behaviour of your application.

Here’s an example of the expected behaviour of a user controller

  it "should flash a notice after succesful signup" do
    User.should_receive(:new).with({"name" => 'Arie'}).and_return(@user)
    @user.should_receive(:save!)
    post 'signup', {:user => {:name => 'Arie'}}
    flash[:notice].should eql(_('Thanks for signing up, you will have to activate your account before you can log in'))
  end

And an example of expected behaviour of a user model

  specify "should be invalid with invalid zip code" do
    @user.attributes = valid_user_attributes.except(:zip)
    @user.zip = 'tralalalalala'
    @user.should_not be_valid
    @user.errors.on(:zip).should eql(_('is invalid'))
    @user.zip = '1234AB'
    @user.should be_valid
  end

The main idea of TDD and BDD is that you write these tests or specifications before writing the actual code. The basic workflow while doing BDD/TDD is:

1. Write tests/specifications

2. Run tests/specifications

3. See them fail because there’s no code yet

4. Code until tests no longer fail

It takes some discipline to strictly follow this pattern, because a future piece of code might seem so trivial, that you want to code it immediately.

rcov resultsWriting the specifications like this takes some time, but you’ll easily make up for it while you’re coding your application. You can use Rcov to check if your specifications cover all your code. When your specifications cover all your code with sensible tests, you can easily refactor your code, because the specifications will make sure your new code works properly.

Also, you can generate human-readable specifications from these rspec files, here’s a snippet of how that looks:

A user
- should be invalid without a username
- should have unique login name
- should be invalid without an email
- should be invalid if email is not between 3 and 100 characters in length
- should have unique email address

The UserController
- should redirect to profile after successfull activation
- should flash a notice when a valid activation code was used
- should flash an error when an invalid activation code was used

In combination with AutoTest, BDD is already saving me a lot of time during development.

Whenever I’ve changed some of my sourcecode or specifications, the specifications get tested automatically. If something breaks, there’s a small error popup, so you know you should check the AutoTest window for the test where it failed.

autotest error

Spot the typo

‘The User Controller should flash an error when an invalid activation code was used‘ FAILED
expected “Unable to activate the account.”, got “Unable to activate the accnt.” (using .eql?)

./spec/controllers/user_controller_spec.rb:29:
script/spec:4:

If all tests pass you get a cheerful message.

AutoTest success

Custom Ubuntu live CD

October2

Ubuntu logoIn a couple of days/weeks/months two friends and I will be giving a workshop at our school about Ruby On Rails. For this workshop we were looking for a bootable CD that provides a fully functioning Ruby on Rails dev environment.

We looked at RailsLiveCD.org but it wasn’t exactly the way we wanted. And whenever something isn’t exactly as you want in the world of OSS, you can fix it.

It took a great tutorial, some trial/error and a couple of failed CD’s, but finally I managed to get it just the way I wanted.

Ruby on Rails logoThe failed CD’s were due to the fact that ‘qemu’, an emulation program that you can use to test bootable .iso files, ran very slowly on my laptop.

The live CD is based on Ubuntu Feisty. It includes MySQL, vim-ruby, Aptana, ruby, rails and the sample project we’ll be using at the workshop.

No other live cd would have our own project on the disk :)

I’ll post the ISO once we’ve given the workshop.

Update

You can now download the Ubuntu on Rails iso.

Areca HDD temperature in MRTG

August7

I’ve been running my Areca RAID array for a few months now and I’m very pleased with it. The only thing that was bothering me was the lack of MRTG graphs for the attached disks.
The disk temperature is an important thing to monitor, because as Google pointed out, a high disk temperature has a significant effect on drive failure.

HDD temperaturesAreca has made some excellent tools available to monitor your array and attached disks. For example, Areca’s web interface can show you all the disk temperatures.

In Areca’s web interface you have total control over your RAID array. You can add/remove disks, create new arrays and do a check on existing arrays.

But it’s annoying to have to log in to this web interface just to check the temperatures of the disks. Also, it doesn’t come with nice graphs and history information. It just shows the current temperatures.

hddtemp-day.png

Areca has also made a CLI utility. Using this utility you can do the same things as in the web interface. I’ve used the CLI utility to generate the data needed by MRTG. MRTG can only handle 2 datasources in one graph. Having 5 disks total (1 bootdisk, 4 RAID member disks), I would need 3 graphs to monitor the disks. So I decided to create a little BASH script that would take the temperature of the bootdisk, and the average temperature of the 4 RAID disks and feed this to MRTG.

Eggdrop script for controlling HLTV’s

August31

As one of the founders of online gaming community #cs.gather.nl, part of the Gather Network, I’ve had quite some dealings with people cheating in online games, and people calling eachother cheaters.There are various ways to fight cheaters in the game Counter-Strike. First there’s the built-in anti-cheat from the developer, Valve, called Valve Anti-Cheat. Despite it’s name, it does little against most popular cheats.Second there’s a global blacklist of cheaters, called Steambans. This will stop people who have cheated before and have been caught by an alert admin, who submitted a recording of the cheater’s actions to Steambans.

Third, admins of the match can request a player to record his actions to a so called ‘demo’. If the user would be cheating this would show on a demo. However, no sane player would still cheat while recording a demo.
A few years ago Valve released a piece of software that allows you to watch matches. This software was created due to the increasing popularity of Counter-Strike as an “e-Sports’ game.

The software, called HLTV, is basically a proxy server that allows people to watch a match without overloading the gameserver. It has a built-in delay, so that spectating people can’t give vital informatin, like enemy positions, to the players with tools as direct messaging and voice communication.

Read the rest of this entry »

Newer Entries »