April 1, 2008 Comments Off
Over the next couple of posts I thought that I would like to discuss the redevelopment of my hiragana and katakana quiz software. This software originally started out as a command-line Perl script, became a PHP web script, before turning into a Ruby on Rails web application. Unfortunately, although the development language changed and possibilities increased, the overall functionality remained very much trapped in the original design. As I have started in other posts, I have plans for my quiz software, but it remains rather static, so perhaps it would be a good idea to talk about user stories as a way of providing clarity and focus.
I tend to prefer to use development tools that simplify the tasks that I have come to find routine, but perhaps more importantly provide me with a fresh and powerful way of looking at new problems that I need to solve. The latest tool to find me is “user stories”:http://rspec.info/documentation/stories.html with “RSpec”:http://rspec.info. Now, I must say that I was already using RSpec to ‘test’ other Ruby on Rails applications and I think that everyone should try and play around with it for a bit, but user stories — in particular the plain-text flavour of them — are what currently occupy my notebook scribbles.
Let me show a somewhat simplistic and incomplete example of a user story:
Story: starting a quiz
As a visitor
I want to start a quiz
So that I can hopefully learn something
Scenario: quiz doesn't exist
Given a quiz named hiragana
When I start another quiz
Then I should see the 404 error page
And I should see a link to the list of quizes
Scenario: quiz does exist
Given a quiz named hiragana
When I start the quiz
Then I should see the quiz
And I should see a question
We have a story with two scenarios: when the quiz exists and when the quiz doesn’t exist. It is not very interesting, but at least we know that the user should see an error page if they try and start a quiz that doesn’t exist, and that they should also see a list of quizes that are available instead. If the quiz does exist then they should see a question.
This might be useful if we want to ensure that the 404 page is shown when the requested quiz doesn’t exist, but it is not very satisfactory to write down and seems a bit pointless. It also doesn’t help us understand what happens when a user starts a quiz.
One of the main thing that I like about plain text user stories is that I can easily scribble them down on a piece of paper. I can focus on describing my goals without worrying about the implementation details and afterwards even use this “pseudotestcode” directly. The plain text user story also is nicely separated from the implementation code that is needed to make it work and because of this, it is easy to fit an understandable and detailed story in a manageable page or two.
I think I will use the following story in my quiz redevelopment and next time I will discuss other stories, and also how to test these stories.
Story: starting a quiz
As a visitor
I want to start a quiz
So that I can hopefully learn something
Scenario: quiz doesn't exist
Given a quiz named hiragana
And a quiz named katakana
When I start another quiz
Then I should see the 404 error page
And I should see a list of quizes
And the list of quizes should have 2 items
Scenario: default configuration
Given a quiz named hiragana
When I start the quiz
Then I should see the quiz
And I should see a question
And I should see the text "Question 1 of 5"
And there should be 3 textboxes
Scenario: 10 questions
Given a quiz named hiragana
And the quiz has been configured for 10 questions
When I start the quiz
Then I should see the quiz
And I should see "Question 1 of 10"
Scenario: 5 hiragana per question
Given a quiz named hiragana
And the quiz has been configured for 5 hiragana
When I start the quiz
Then I should see the quiz
And there should be 5 textboxes
February 14, 2008 Comments Off
Today after upgrading RSpec I ran a user story that I had just written and received a wonderful error: You have a nil object when you didn't expect it! (NoMethodError). The error occurred while evaluating nil.add_scenario. I didn’t even think to check my user story because the syntax highlighting looked fine and it made sense to me:
Scenario: areas have different types
As an administrator
I want to assign different types to the areas
So that I can structure the home page
Scenario: footer shows page links
Given an area
And area has 5 pages
And area is of type footer
When I view the home page
Then I should see the home page
And I should see the footer section
And the list section should contain 0 areas
And the footer section should contain 5 links
Of course, if I actually bothered to read it properly then I would have seen that the first line should have read:
Story: areas have different types
Moral of the story: even if the code that you have to write is small, always assume that you are capable of making silly mistakes!
December 2, 2007 Comments Off
Update: I am trying out The Unstandard WordPress theme and find it rather interesting especially the idea of creating an image for each of my old posts.
I do think that it is about time that I changed the theme of this website. I don’t know if anyone remembers the original hand-crufted theme but luckily archive.org is able to help me out:
![[kumo.it] website in June 2002](http://www.kumo.it/wp-content/uploads/2007/12/kumoit-20071202.thumbnail.png)
The main problem that I have with the current design is the list of pages that is just too long and distracting. I know that I could use some sort of list folding plugin, but I was hoping that there was a better alternative — perhaps even a redesign of the website rather than just choosing a different theme.
Import features are:
- News/blog posts
- Static pages with subpages — I might have posts that talk about BeOS software, but there is a specific page for each piece of software
- Flickr photos!
- Spam plugin — I hardly get any comments any more, but akismet has blocked over 45,000 spam
June 8, 2007 Comments Off
Interesting times indeed as I am finally able to run Haiku at a decent speed under OSX (does that make it Haiku.app?). The network works too which is very useful if I am ever going to do anything with my projects.
!http://www.kumo.it/wp-content/uploads/2007/06/haiku.png!
I have moved the BeOS open source survey to the “BeOS”:/beos page.
April 30, 2007 Comments Off
Yesterday we wanted to play 3D tictactoe on my palm, but we didn’t have any such game. Now I could have used OnBoardC or plua to ‘quickly’ write a game but I didn’t have 2 weeks or a collection of icons at hand. Instead I found myself using Opera on my Nintendo DS to browse the internet but I couldn’t download the zip file.
So, rebooting into DSLinux (using a supercard and sd card) I could use wget to download file to the memory card and then unzip it.
All I needed to do then was put the memory card in the palm and copy it … after playing the game I wished that I could write the game for the Nintendo DS.
March 8, 2007 Comments Off
This is more of a note to myself, but when I was a lad at lot of the children’s drama that was shown on childrens tv was Australian or from New Zealand. Thinking back it was quite impressive as there was (as far as I can remember):
(all links point to wikipedia)
Does anyone remember anything else?
November 23, 2006 Comments Off
I have started using the better assert_difference that was posted at blog.caboo.se to improve my rails tests. This allowed me to write tests such as:
assert_difference Item, :count do
Item.create(:name => "Monkey magic")
end
This replaces:
item_count = Item.count
Item.create(:name => "Monkey magic")
assert_difference, item_count + 1, Item.count
but I also wanted to be able to test if emails were sent by writing:
assert_difference ActionMailer::Base.deliveries, :size do
SystemNotifier.deliver_important_message
end
That didn’t work and it was noted on that website that the code didn’t work properly with arrays so I have modified the assert_difference method to check if the objects respond to the method (e.g. size) and act accordingly:
def assert_difference(objects, method = nil, difference = 1)
initial_values = []
if objects.respond_to? method
initial_values = objects.send(method)
else
objects = [objects].flatten
initial_values = objects.inject([]) { |sum,obj| sum << obj.send(method) }
end
yield
if difference.nil?
objects.each_with_index { |obj,i|
assert_not_equal initial_values[i], obj.send(method) #, "#{obj}##{method}"
}
else
if objects.respond_to? method
assert_equal initial_values + difference, objects.send(method) #, "#{objects}##{method}"
else
objects.each_with_index { |obj,i|
assert_equal initial_values[i] + difference, obj.send(method) #, "#{obj}##{method}"
}
end
end
end
I have tested it for an array such as ActionMailer::Base.deliveries but I haven't tested it in other situations so hopefully it won't create any problems.
The rspec version of this is:
def assert_difference(objects, method = nil, difference = 1)
initial_values = []
if objects.respond_to? method
initial_values = objects.send(method)
else
objects = [objects].flatten
initial_values = objects.inject([]) { |sum,obj| sum << obj.send(method) }
end
yield
if difference.nil?
objects.each_with_index { |obj,i|
initial_values[i].should_not_equal obj.send(method) #, "#{obj}##{method}"
}
else
if objects.respond_to? method
(initial_values + difference).should_eql objects.send(method) #, "#{objects}##{method}"
else
objects.each_with_index { |obj,i|
(initial_values[i] + difference).should_eql obj.send(method) #, "#{obj}##{method}"
}
end
end
end
September 17, 2006 Comments Off
A couple of nights ago I decided that it was time to see if I could get BeOS to work on my iBook (it worked but it was very slow). The only way I could get it to work was with emulation. I found the information on various places on the Internet but I forgot to note down where I found it from so I am recreating it here (so that at least I don’t forget how it was done).
For now I am trying to use just the simple BeOS 5 Personal Edition.
- Download the BeOS R5 Personal Edition for Linux from BeBits
- Extract the file that you just downloaded and if you want to, place image.be and floppy.img somewhere
- Install _qemu_ which is a PC emulator. I installed it from http://stegefin.free.fr/qemu/qemu.dmg as suggested on the Haiku Wiki
At this point, you should open up a Terminal window and cd to the location where image.be and floppy.img are. Both files are needed to get BeOS PE to run and so the following should be typed:
qemu -fda floppy.img -hda image.be -boot a -m 128 -user-net
- -fda floppy.img
- The floppy disk is _floppy.img_
- -hda image.be
- The hard disk is _image.be_
- -boot a
- Boot from drive a
- -m 128
- Provide 128 meg of memory
- -user-net
- Creates a private network (?)
After a while BeOS will be running in greyscale. Either I would have to enable the safe video mode everytime I booted BeOS or I would have to use one of the pieces of software on BeBits to force the video mode. I couldn’t get the network to work so I was stuck with the problem of how to transfer files to BeOS. I tried to make a dmg but it didn’t work so in the end I made a CD image using the following command:
hdiutil makehybrid -o stuff_for_beos.iso -iso DIRECTORY
At that point the CD image can be passed to qemu by adding -cdrom ISONAME to the qemu command:
qemu -fda floppy.img -hda image.be -cdrom stuff_for_beos.iso -boot a -m 128 -user-net