Eyes, JAPAN Blog > Testing, testing, testing

Testing, testing, testing

denvazh

この記事は1年以上前に書かれたもので、内容が古い可能性がありますのでご注意ください。

I development I tend to be very lazy, I try as much as possible NOT to write extra line of code if its not necessary. Of course, it wasn’t always like this.
When I was at the university, I was writing quite a lot of code, with a lot of methods, variables and quite complex logic. Over the time, I realized importance
of writing as little code as possible.

Typically, any given developer in the past would write code like this:
1) be told to implement super awesome feature
2) estimate how much time it would take ( i.e. guess, roll dice )
3) write code
4) pray that code is working
5) test if it works
6) enjoy the day if everything was fine
7) repeat step 3) if bug was found

In the past, I’ve been developing like this and found it to be quite stressful, and in the long run it makes code unmaintainable,
because refactoring and improving code quality after release would mean additional expenses.

Gradually, I try to improve my skills and overall code quality adopting test driven development. Of course it has some downsides and it cannot apply to
certain project requirements ( typically very exotic ones ), but benefits greatly overweight any drawbacks.

Currently, I’m educating myself into using cucumber framework to describe and test rails development. There are many books and guidelines available online, so
I don’t want to repeat everything here, but I would show small sample, which hopefully draws more attention to importance of testing.

Assuming we use rails and cucumber was already configured, we write description of one feature we like to add.
For example, we like to enable authenticated users to access their information with simple GET request.

First, we create file features/userinfo.feature and then fill it in with necessary content.

In the beginning, we have to describe feature:

Feature: UserInfo
    In order to make it possible for authenticated users to access their account information,
    I need to generate response in json format

Next, for this feature we think over and add necessary scenarios. Here it is important to describe scenario as a sequence of 1) initial condition, 2) action and 3) result.
In Cucumber corresponding reserved terms has to be used 1) Given, 2) When, 3) Then. Complete scenario should look like below:

Scenario: User Account information
    Given the client authenticate with username and password
    When the client send GET request to 'api/v1/user/account'
    Then the response code should be "200"
    And the response body should be JSON:
    """
    {
        "id": "1",
        "name": "TestUser",
        "created_at": "2014-02-12T06:24:19Z",
        "modified_at": "2014-02-12T06:24:19Z"
    }
    """

Now, we have feature definition, and we can just execute cucumber to see what it returns:

$: rake cucumber feature/userinfo.feature
Feature: UserInfo
  In order to make it possible for authenticated users to access their account information,
  I need to generate response in json format

  Scenario: User Account information                          # features/userinfo.feature:5
    Given the client authenticate with username and password  # features/userinfo.feature:6
      Undefined step: "the client authenticate with username and password" (Cucumber::Undefined)
      features/userinfo.feature:6:in `Given the client authenticate with username and password'
    When the client send GET request to 'api/v1/user/account' # features/userinfo.feature:7
      Undefined step: "the client send GET request to 'api/v1/user/account'" (Cucumber::Undefined)
      features/userinfo.feature:7:in `When the client send GET request to 'api/v1/user/account''
    Then the response code should be "200"                    # features/userinfo.feature:8
      Undefined step: "the response code should be "200"" (Cucumber::Undefined)
      features/userinfo.feature:8:in `Then the response code should be "200"'
    And the response body should be JSON:                     # features/userinfo.feature:9
      """
      {
      "id": "1",
      "name": "TestUser",
      "created_at": "2014-02-12T06:24:19Z",
      "modified_at": "2014-02-12T06:24:19Z"
      }
      """
      Undefined step: "the response body should be JSON:" (Cucumber::Undefined)
      features/userinfo.feature:9:in `And the response body should be JSON:'

2 scenarios (2 undefined)
8 steps (8 undefined)
0m0.046s

Additionally, it would produce code snippets, that can be used for creating so-called step definition for each scenario

You can implement step definitions for undefined steps with these snippets:

Given(/^the client authenticate with username and password$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^the response code should be "(.*?)"$/) do |arg1|
  pending # express the regexp above with the code you wish you had
end

Then(/^the response body should be JSON:$/) do |string|
  pending # express the regexp above with the code you wish you had
end

When(/^the client send GET request to 'api\/v(\d+)\/user\/account'$/) do |arg1|
  pending # express the regexp above with the code you wish you had
end

Implementing step definition would bring us to actual tests we can actually use to test source code we will be writing.

Comments are closed.