Using Aspects in C# With POSTSharp

Posted on September 5th, 2009 by macskeptic

A little bit about aspect oriented programming (AOP)

For the last few couple of years, as the hardware kept getting cheaper and more powerful, the programming languages core concern has been moved from performance to clarity and maintainability.

While in the past you had to keep asking yourself which algorithm was the best to, say, iterate over a list, now it is far from being a major concern. What it gives us, developers, is a chance to focus our precious time and effort on more important matters in our daily jobs, like readability and maintainability.

With these new priorities in mind, the industry have come up with the object oriented paradigm - which focus on mapping real world entities straight to code equivalents.

However, a big troublemaker we still face every now and then while developing software are the crosscutting concerns - generating replicated code all around our projects.  The main examples I can come up with about this are:

  • Logging;
  • Authentication;
  • Open/Close connections;
  • Exception handling.

These concerns not seldom can be seen being dealt with using very similar (if not the exact same) blocks of code alongside many of our classes, even though it is a relatively unique matter.

To address this problem came the aspect oriented paradigm. Its purpose is to complement the OOP, eliminating the need for replication and adding clarity to your code. What follows in this article is a very quick example of the possible benefits that using aspects can bring you while developing software.

 

Learning by Example

The immediate concern I have about having code all over the place to handle a concern that should be centralized is that, when this thing needs to be changed for some reason, you will have to manually go to every point where the code is replicated and fix it. Every good programmer knows that manual tasks like this are bound to catastrophic failure.

Next, let’s implement an Account class, that will provide deposit and withdraw functionality. We shall start, of course, by the tests:

[TestMethod]
public void WithdrawShouldDecreaseBalance()
{
    Account account1 = AccountBuilder.New
        .BelongingTo("MACSkeptic")
        .WithInitialBalance(200.95M)
        .IdentifiedBy(773)
        .Instance;

    Assert.AreEqual(100.95M, account1.Withdraw(100).CurrentBalance);
    Assert.AreEqual(0.0M, account1.Withdraw(100.95M).CurrentBalance);
    Assert.AreEqual(-10.0M, account1.Withdraw(10.00M).CurrentBalance);
}

[TestMethod]
public void DepositShouldIncreaseBalance()
{
    Account account1 = AccountBuilder.New
        .BelongingTo("MACSkeptic")
        .WithInitialBalance(-50.42M)
        .IdentifiedBy(666)
        .Instance;

    Assert.AreEqual(-0.42M, account1.Deposit(50).CurrentBalance);
    Assert.AreEqual(79.58M, account1.Deposit(80).CurrentBalance);
}

To satisfy the behavior denoted just above we shall implement the Account class, like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Codevil.MACSkeptic.PostSharpExample.Entities
{
    public class Account
    {
        public long Number { get; set; }
        public string Owner { get; set; }
        public decimal CurrentBalance { get { return this.currentBalance; } }

        private decimal currentBalance;

        public Account(long number, string owner)
            : this(number, owner, 0)
        {
        }

        public Account(long number, string owner, decimal initialBalance)
        {
            this.Number = number;
            this.Owner = owner;
            this.currentBalance = initialBalance;
        }

        public Account Deposit(decimal howMuch)
        {
            Console.WriteLine(string.Format(
                "New deposit transaction on account {0}. Balance before operation is ${1}.",
                this.Number,
                this.CurrentBalance));

            Console.WriteLine(string.Format(
                "Depositing ${0} on account {1}.", howMuch, this.Number));

            this.currentBalance += howMuch;

            Console.WriteLine(string.Format(
                "Finished deposit transaction on account {0}. Balance after the operation is ${1}.",
                this.Number,
                this.CurrentBalance));

            return this;
        }

        public Account Withdraw(decimal howMuch)
        {
            Console.WriteLine(string.Format(
                "New withdraw transaction on account {0}. Balance before operation is ${1}.",
                this.Number,
                this.CurrentBalance));

            Console.WriteLine(string.Format(
                "Withdrawing ${0} on account {1}.", howMuch, this.Number));

            this.currentBalance -= howMuch;

            Console.WriteLine(string.Format(
                "Finished withdraw transaction on account {0}. Balance after the operation is ${1}.",
                this.Number,
                this.CurrentBalance));

            return this;
        }
    }
}

As you can see, our account allows for deposits and withdrawals with no concern about the overall balance at the moment. Which means, if you withdraw more than you have, you’re going to get in debt.

To keep things simple and focus on what really matters here, I’m using the console as the log of the application.

By the code above, we can already spot a clear repetition pattern on the logging concern related code. Let’s try to fix it with traditional OO refactoring, extract method:

public Account Deposit(decimal howMuch)
{
    this.LogTransactionStarting("deposit");
    this.LogTransactionDetails("Depositing", howMuch);
    this.currentBalance += howMuch;
    this.LogTransactionFinished("deposit");
    return this;
}
public Account Withdraw(decimal howMuch)
{
    this.LogTransactionStarting("withdraw");
    this.LogTransactionDetails("Withdrawing", howMuch);
    this.currentBalance -= howMuch;
    this.LogTransactionFinished("withdraw");
    return this;
}
private void LogTransactionStarting(string action)
{
    Console.WriteLine(string.Format(
        "New {2} transaction on account {0}. Balance before operation is ${1}.",
        this.Number,
        this.CurrentBalance,
        action));
}
private void LogTransactionDetails(string action, decimal howMuch)
{
    Console.WriteLine(string.Format(
        "{2} ${0} on account {1}.", howMuch, this.Number, action));
}
private void LogTransactionFinished(string action)
{
    Console.WriteLine(string.Format(
        "Finished {2} transaction on account {0}. Balance after the operation is ${1}.",
        this.Number,
        this.CurrentBalance,
        action));
}

Ok, that’s a little better now, with a little less repetition, right? But, as you can see, the account class still has to be concerned with keeping a log of its transactions. Using just OO we could move the logging methods to another class, like a service. But still we would have to call them explicitly from inside the account class. The problem with this is that, when you read this code, you will most likely get distracted from the main point (the business logic) because of the logging concerned method calls.

There is a well known saying about how you design your classes on an OOP project: if you have to use an "and" to describe what your class does, that smells like bad design - more specifically, your class is most likely overloaded with responsibilities that shouldn’t be there. In our example so far, the account class is concerned with the account movements and the logging.

Here we can classify the main points at which we wish to add logging:

  • Before any transaction;
  • Right when the transaction will be executed, with details concerning values involved;
  • Right after the transaction.

A very interesting and powerful tool for aspect development in .NET is the PostSharp framework - its slogan: "make sense, not code" says a lot about the main idea of the AOP. For the next tasks on this article, we will need to download PostSharp (I’m using the version 1.5). It can be downloaded clicking here (you will need to register, which is free, by clicking here).

After installing PostSharp, it is time to add references to PostSharp.Laos and PostSharp.Public to our project, like this:

image

PostSharp’s detailed documentation can be accessed by clicking here.

Our account class will make use of the following aspect concepts/classes:

First things first, let’s get to the on method boundary aspect implementation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Laos;
using Codevil.MACSkeptic.PostSharpExample.Entities;

namespace Codevil.MACSkeptic.PostSharpExample.Aspects
{
    [Serializable]
    public class LogAccountStatusBeforeAndAfterTransaction : OnMethodBoundaryAspect
    {
        public override void OnEntry(MethodExecutionEventArgs eventArgs)
        {
            Account account = (Account)eventArgs.Instance;
            Console.WriteLine(string.Format(
                "New {2} transaction on account {0}. Balance before operation is ${1}.",
                account.Number,
                account.CurrentBalance,
                eventArgs.Method.Name));
        }
        public override void OnExit(MethodExecutionEventArgs eventArgs)
        {
            Account account = (Account)eventArgs.Instance;
            Console.WriteLine(string.Format(
               "Finished {2} transaction on account {0}. Balance after the operation is ${1}.",
               account.Number,
               account.CurrentBalance,
               eventArgs.Method.Name));
        }
    }
}

The aspect "on method boundary" allows us to determine pieces of code that will be executed right before and right after the original method was called, like you can see in the snippet just above.  It is very important to notice that all aspect implementations with PostSharp must be serializable.

Since we moved the "before transaction" and "after transaction" logging concern to this aspect, let’s see how it can help us with our account class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Codevil.MACSkeptic.PostSharpExample.Aspects;

namespace Codevil.MACSkeptic.PostSharpExample.Entities
{
    public class Account
    {
        public long Number { get; set; }
        public string Owner { get; set; }
        public decimal CurrentBalance { get { return this.currentBalance; } }
        private decimal currentBalance;

        public Account(long number, string owner)
            : this(number, owner, 0)
        {
        }

        public Account(long number, string owner, decimal initialBalance)
        {
            this.Number = number;
            this.Owner = owner;
            this.currentBalance = initialBalance;
        }
        [LogAccountStatusBeforeAndAfterTransaction]
        public Account Deposit(decimal howMuch)
        {
            this.LogTransactionDetails("Depositing", howMuch);
            this.currentBalance += howMuch;
            return this;
        }
        [LogAccountStatusBeforeAndAfterTransaction]
        public Account Withdraw(decimal howMuch)
        {
            this.LogTransactionDetails("Withdrawing", howMuch);
            this.currentBalance -= howMuch;
            return this;
        }
        private void LogTransactionDetails(string action, decimal howMuch)
        {
            Console.WriteLine(string.Format(
                "{2} ${0} on account {1}.", howMuch, this.Number, action));
        }
    }
}

We can see the attributes added on lines #27 and #34 - they just mark where the logging aspect is supposed to act.

Now, let’s see how the "on method invocation" aspect works on practice:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Laos;
using Codevil.MACSkeptic.PostSharpExample.Entities;

namespace Codevil.MACSkeptic.PostSharpExample.Aspects
{
    [Serializable]
    public class LogAccountTransactionDetails : OnMethodInvocationAspect
    {
        public override void OnInvocation(MethodInvocationEventArgs eventArgs)
        {
            Account account = (Account)eventArgs.Instance;
            Console.WriteLine(string.Format(
                "{2} ${0} on account {1}.",
                eventArgs.GetArgumentArray().First(),
                account.Number,
                eventArgs.Method.Name));
            eventArgs.Proceed();
        }
    }
}

Again, we’ve just moved the original implementation of the logging method (which was once on the account class) to here. Here it is interesting to notice that the eventArgs parameter gives us access to some really neat stuff, like:

  • The current instance of the class in which the aspect is being applied;
  • The method being called;
  • The parameters used on the method call.

Notice the call to the method "proceed" above (line #21)? This method tells the weaver that the original method should be called right at this point. This concept has some immediate consequences, if needed, we could:

  • Switch the original parameters with new ones - to do that, you just need to pass the new ones to the proceed method;
  • Not even call the original method - to do that, you just need to omit the call to the proceed method altogether.

With this, we’ve just moved every last bit of logging concern straight out of our account class, into our logging aspects. So, let’s see how the account class has changed:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Codevil.MACSkeptic.PostSharpExample.Aspects;

namespace Codevil.MACSkeptic.PostSharpExample.Entities
{
    public class Account
    {
        public long Number { get; set; }
        public string Owner { get; set; }
        public decimal CurrentBalance { get { return this.currentBalance; } }
        private decimal currentBalance;

        public Account(long number, string owner)
            : this(number, owner, 0)
        {
        }

        public Account(long number, string owner, decimal initialBalance)
        {
            this.Number = number;
            this.Owner = owner;
            this.currentBalance = initialBalance;
        }
        [LogAccountStatusBeforeAndAfterTransaction]
        [LogAccountTransactionDetails]
        public Account Deposit(decimal howMuch)
        {
            this.currentBalance += howMuch;
            return this;
        }
        [LogAccountStatusBeforeAndAfterTransaction]
        [LogAccountTransactionDetails]
        public Account Withdraw(decimal howMuch)
        {
            this.currentBalance -= howMuch;
            return this;
        }
    }
}

Before anything else, by using a regular expression we can clean up this code even more:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Codevil.MACSkeptic.PostSharpExample.Aspects;

namespace Codevil.MACSkeptic.PostSharpExample.Entities
{
    [LogAccountStatusBeforeAndAfterTransaction(
		AttributeTargetMembers = "regex:(Deposit)|(Withdraw)")]
    [LogAccountTransactionDetails(
		AttributeTargetMembers = "regex:(Deposit)|(Withdraw)")]
    public class Account
    {
        public long Number { get; set; }
        public string Owner { get; set; }
        public decimal CurrentBalance { get { return this.currentBalance; } }
        private decimal currentBalance;

        public Account(long number, string owner)
            : this(number, owner, 0)
        {
        }

        public Account(long number, string owner, decimal initialBalance)
        {
            this.Number = number;
            this.Owner = owner;
            this.currentBalance = initialBalance;
        }
        public Account Deposit(decimal howMuch)
        {
            this.currentBalance += howMuch;
            return this;
        }
        public Account Withdraw(decimal howMuch)
        {
            this.currentBalance -= howMuch;
            return this;
        }
    }
}

No more logging concern inside our account class ;).

It gets even better! Now that we have a little better understanding of the PostSharp framework, we can get rid of the "on method boundary" aspect. To do so, we just need to make some adjusts to the "on method invocation aspect", like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Laos;
using Codevil.MACSkeptic.PostSharpExample.Entities;

namespace Codevil.MACSkeptic.PostSharpExample.Aspects
{
    [Serializable]
    public class LogAccountTransactionDetails : OnMethodInvocationAspect
    {
        public override void OnInvocation(MethodInvocationEventArgs eventArgs)
        {
            Account account = (Account)eventArgs.Instance;

            LogTransactionStarting(eventArgs, account);
            LogTransactionDetails(eventArgs, account);
            eventArgs.Proceed();
            LogTransactionFinished(eventArgs, account);
        }
        private static void LogTransactionDetails(
			MethodInvocationEventArgs eventArgs, Account account)
        {
            Console.WriteLine(string.Format(
                "{2} ${0} on account {1}.",
                eventArgs.GetArgumentArray().First(),
                account.Number,
                eventArgs.Method.Name));
        }
        private static void LogTransactionStarting(
			MethodInvocationEventArgs eventArgs, Account account)
        {
            Console.WriteLine(string.Format(
                "New {2} transaction on account {0}. Balance before operation is ${1}.",
                account.Number,
                account.CurrentBalance,
                eventArgs.Method.Name));
        }
        private static void LogTransactionFinished(
			MethodInvocationEventArgs eventArgs, Account account)
        {
            Console.WriteLine(string.Format(
               "Finished {2} transaction on account {0}. Balance after the operation is ${1}.",
               account.Number,
               account.CurrentBalance,
               eventArgs.Method.Name));
        }
    }
}

Notice that first we log the transaction start (line #17), then the transaction details, including parameters (line #18), only then we call the original method (line #19), and then, finally we log the transaction end (line #20). With this, we just replicated the original behavior using the two aspects, but using only the "on method invocation" =). Now, let’s get rid of our, now useless, aspect "on method boundary" on the account class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Codevil.MACSkeptic.PostSharpExample.Aspects;

namespace Codevil.MACSkeptic.PostSharpExample.Entities
{
    [LogAccountTransactionDetails(
		AttributeTargetMembers = "regex:(Deposit)|(Withdraw)")]
    public class Account
    {
        public long Number { get; set; }
        public string Owner { get; set; }
        public decimal CurrentBalance { get { return this.currentBalance; } }
        private decimal currentBalance;
        private const decimal DefaultInitialBalance = 0;

        public Account(long number, string owner)
            : this(number, owner, DefaultInitialBalance)
        {
        }
        public Account(long number, string owner, decimal initialBalance)
        {
            this.Number = number;
            this.Owner = owner;
            this.currentBalance = initialBalance;
        }

        public Account Deposit(decimal howMuch)
        {
            this.currentBalance += howMuch;
            return this;
        }
        public Account Withdraw(decimal howMuch)
        {
            this.currentBalance -= howMuch;
            return this;
        }
    }
}

Even in this small example you can see how we just got rid of, at the very least, 6 lines of alien code that were inside of our account class (6 lines considering the best case scenario using just OOP, if you moved the logging implementation to a service). These lines were strictly concerned with logging, which should be none of our account class concern. In their place, we had to add just a single line declaring an aspect of the behavior desired across our account class.

Just to keep things clear, my point here is not that less code is necessarily better (although it usually is), but that you should separate the responsibilities very clearly and write the code where it really belongs.

That’s all for now folks, I hope you’ve liked this and got a grasp on how powerful AOP can be. I strongly recommend that those interested in using aspects in real projects get to read carefully the PostSharp documentation to check the details about optimization and performance.

Like usual, the codebase for this article is on my github, and can be downloaded here. Feel free to leave your doubts, criticisms, suggestions and feelings at the comments.

Cheers, and see you next time ;).

References:

Recommended Reading:

BASIC AMQP illustrated

Posted on July 29th, 2009 by Koiti Takahashi

After a little more than one year of heavy code production and few innovations, although I could explore some interesting stuff like WCF and RESTful, our team finally got a time to “invent” something new. This time, we have to rewrite a legacy system (mainly a single stored procedure *arghh*) that verifies the clients with overdue payments, notifies them about it and stop provisioning services until their debts are paid off. As it can be imagined, it has many responsibilities belonging to different domains, consequently, belonging to different teams of our company.

My team is responsible for verifying the financial issues and should inform another team, which takes care of services provisioning, about the debtors. Thus, it is necessary to define how our systems will communicate with each other. One of the suggested solutions was AMQP standard for message queuing and that’s exactly what I will talk about.

AMQP stands for Advanced Message Queuing Protocol and its main purpose is to enable full functional interoperability between conforming clients and messaging middleware servers (aka. brokers). That is, AMQP defines a standard protocol for publishing, queueing, storing and consuming messages. The message producer utilizes a client API to publish message into a server. The server/broker will then place the message into a queue and store it while it is not consumed. At last, a consumer application will accept the messages stored in a queue and remove them from it.

The AMQP overall model is represented below:

amqp_model

 

Server

An AMQP server, like RabbitMQ or Qpid, is a data server that accepts messages, routes them to different consumers (queues) according to some arbitrary criteria (bindings) and store the messages while not consumed.

 

Virtual Hosts

A virtual host is somewhat similar to a workspace where a user connects. It comprises a set of exchanges, message queues and bindings. Even though an user is authenticated into the server, it may not successfully connect into a virtual host if it is not authorized. The authorization for the server users are granted for each virtual host.

 

Exchange

It can be said that the exchange possess the most important role among the AMQP middleware server components. It is delegated to route the messages to the queues matching the routing information, like an routing key, with the previously set bindings. Exchanges can also route messages according to its type. Some of them are explained below:

  1. Direct: direct type exchange routes a given message matching exactly the message routing key with the queue binding key. This type of exchange is a MUST in AMQP server implementation.
  2. Fanout: fanout type exchange routes a given message to all bound queues regardless of it’s routing key. The fanout also is a MUST in the broker.
  3. Topic: topic type exchange routes a given message verifying if the message key matches the queue binding key. For instance, let’s suppose that we have created a queue belonging to an exchange of type topic and it is bound to the exchange with a binding key like “sport.#”. Now, imagine a message sent to the exchange with a routing key “sport.soccer”. The key “sport.#” says that any message with a key “sport.anything” must be routed to the queue with such binding key. The ‘#’ means matches zero or more words and ‘*’ means matches one word. Topic is a SHOULD be implement type in AMQP server.

 

Bindings

A binding is a constraint between a queue and an exchange, setting a criterion for message routing.

 

Routing Keys/Binding Keys

As explained above, routing keys are message identifiers. In the other hand, binding keys are bindings identifiers. Duh, you may say. I agree. But it is pretty much that. Binding keys exists to tell the exchange that a message with a key that matches the routing key should be addressed to its related queue.

 

Message Queues

Message queues are the consumer’s message inboxes. It keeps the messages in memory or disk until they are read by the consumer in a FIFO politics.

To illustrate AMQP messaging flow in a more comprehensible manner, let’s take a look at the following comic (special thanks to KreuZ for helping me with the figures), representing a Direct Type Exchange:

3-koma_02

3-koma_04

3-koma_06

In these frames, we have a Message producer that sends a message with a “cars” key to the Exchange. We have also two queues: John’s queue and Kate’s queue. John’s queue says that he likes “cars”. That is, he is bounded to the exchange saying that any message related to “cars” (binding key) is of his business.

When the Exchange receives the given message, he knows that John’s queue is interested in "cars”, Kate’s queue is interested in “cookies”, and that he has a message about “cars” in hands. So, with these information, he passes the message to John’s queue but not to Kate’s queue, since the message “subject” matches exactly with what John’s queue wants.

Well, that’s an introductory post about AMQP that I wanted to have it here because my next post will be about real code using AMQP implementations. For more information about AMQP, please refer to its site.

Finally, I hope that the illustration helps for a better understanding of the basic principles of AMQP protocol and I would appreciate your comments and mainly, suggestion and critics.

TDD - Beyond The Buzzwords

Posted on July 26th, 2009 by macskeptic

The "Beyond The Buzzwords" series is focused on giving those who are starting to write automated tests a practical overview, so that they begin to get a grasp on the mechanics of doing it. Also, to encourage those who don’t do it yet to begin doing so. That said, the idea is to not be over theoretical and purist, scaring away newcomers - but keeping both feet firmly on the arduous ground in which lies the path to solid automated testing practices.

This is the second article in the series. Today I’m going to talk about TDD - taking a slightly different approach on the bookstore application we developed on the last one.

TDD stands for Test Driven Design - it means to let your tests guide your software development at each and every step of the way to quality and highly maintainable code. It is mainly based on a relentless three step heartbeat-like pattern that must not be disturbed:

Red => Green => Refactoring => Red

This very simple pattern stands at the very core of the TDD mindset. So, let’s take a look at the meaning of each work [if you have not guessed it already]:

  • Red stands for writing a test that describes a single simple and punctual functionality, then running that test to watch it fails. Yes, you should [must] write your tests first, otherwise they’ll nothing but re-hashes of your actual implementation code, therefore testing nothing in terms of domain logic per se.
  • Green stands for writing the bare minimum of code necessary to make the test pass. This is important, don’t jump to implement extra functionality just because you’re already coding anyway - keep it minimal, simple and focused on making the test pass, you can care about design later.
  • Refactoring stands for making your code better, from a design perspective, applying some refactoring principle [Martin Fowler wrote a book on this subject, published in 1999 - with this being a pretty good catalogue of commonly used refactoring patterns]. That must only be done when all your tests are passing, and they should still pass once you’ve done refactoring - otherwise it means that your embellishment  of the code actually broke it.

If you are willing to take the textbook approach to TDD, then the aforementioned definitions mean that not a single line of code shall be written if there isn’t a test failing because of the lack of that very specific line. And this is definitely a statement not to be taken lightly.

While BDD seems to lack support from proper tools for the modern widespread mainstream programming languages (JBehave and NBehave still have ways to go before standing up to cucumber) - TDD, on the other hand, has  plenty of them for virtually any platform you pick. Since our bookstore is a rails application, we’ll be using the ruby option that I like the most: rspec.

Let’s just say we are given the exact same story to work with than last time, in case you’ve forgot it:

As the bookstore owner
I want to be able to register new books including rating and author
So that I don’t need to call the IT guys to do it for me manually every single time

That being said, let’s see how it works on practice:

rails bookstore_tdd --database=mysql
cd bookstore_tdd
rake db:create:all
rake db:migrate
script/generate rspec

The last command shown above shall generate some infrastructure for testing with rspec on your rails application.

Now, let’s create the book model, instead of the default rails generator we’re going to use the rspec one, like this:

script/generate rspec_model book title:string author:string rating:decimal synopsis:text

Also let’s create the books table both on development and on test environment

rake db:migrate
rake db:migrate RAILS_ENV=test

Since we’ve used the rspec generator for the model, it already created an skeleton so that we can test it, you can check it on the spec/models/book_file.rb file. It should look like this:

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe Book do
  before(:each) do
    @valid_attributes = {
      :title => "value for title",
      :author => "value for author",
      :rating => 9.99,
      :synopsis => "value for synopsis"
    }
  end

  it "should create a new instance given valid attributes" do
    Book.create!(@valid_attributes)
  end
end

Since the whole code for persistence of the book model is handled by the active record framework, we don’t need to bother to write tests to ensure that it works - since such test suite is already done by those who develop it.

But, for the sake of exemplifying the possibilities, let’s say that our business policy says that it is OK to have a book without synopsis and/or rating, but its title and author are mandatory properties. The previous statement describes a very specific rule to our application - the best way to express it is writting a test to make it clear. Well written tests can virtually replace any need for external documentation - in other words: your tests should describe as clearly as possible the particularities of your application.

Keep in mind that rspec is a very flexible tool, and can be used in many different ways to accomplish the same goal. I’m going to show an approach that I am particularly inclined to use very often. Let’s change the placeholder code that was automatically inserted on the book spec to this:

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe Book, "with all attributes properly set" do
  before(:each) do
    @valid_attributes = {
      :title => "value for title",
      :author => "value for author",
      :rating => 9.99,
      :synopsis => "value for synopsis"
    }
  end

  it "should create a new instance given valid attributes" do
    lambda { Book.create!(@valid_attributes) }.should_not raise_error
  end
end

describe Book, "missing rating and synopsis" do
  before(:each) do
    @valid_attributes = {
      :title => "value for title",
      :author => "value for author"
    }
  end

  it "should be OK, since rating and synopsis are optional" do
    lambda { Book.create!(@valid_attributes) }.should_not raise_error
  end
end

describe Book, "missing author" do
  before(:each) do
    @invalid_attributes = {
      :title => "value for title",
      :rating => 9.99,
      :synopsis => "value for synopsis"
    }
  end

  it "should not be allowed, because author is mandatory" do
    # lambda { Book.create!(@invalid_attributes) }.should raise_error <= this is another way to do it
    book = Book.create(@invalid_attributes)
    book.errors_on(:author).should_not be_empty
  end
end

describe Book, "missing title" do
  before(:each) do
    @invalid_attributes = {
      :author => "value for author",
      :rating => 9.99,
      :synopsis => "value for synopsis"
    }
  end

  it "should not be allowed, because title is mandatory" do
    # lambda { Book.create!(@invalid_attributes) }.should raise_error  <= this is another way to do it
    book = Book.create(@invalid_attributes)
    book.errors_on(:title).should_not be_empty
  end
end

That was a lot of code, so let’s take a look at some crucial concepts:

  • With rspec you don’t write tests for your classes, you write a description about what is expected from them - therefore the use of the “describe” syntax
  • Some people defend fewer contexts for each model, I particularly like to create a new describe block for each kind of scenario
  • Rspec defines the methods “should” and “should_not” for every object, so you can evaluate the result using them - a full list of the possibilites can be consulted here

You probably have noticed that each test has been written using the prefix “it” followed by a natural language sentence, right? Because of that, the outcome we get when we run our specs [rake spec] is something like this:

FF..

1)
'Book missing title should not be allowed, because title is mandatory' FAILED
expected empty? to return false, got true
./spec/models/book_spec.rb:59:

2)
'Book missing author should not be allowed, because author is mandatory' FAILED
expected empty? to return false, got true
./spec/models/book_spec.rb:43:

Finished in 0.054108 seconds

4 examples, 2 failures

As I already stated before, from the excerpt shown just above - if you plan your tests to pinpoint each specifical detail of functionality you might even be able to never again need to run a debugging session. By looking at the result shown above we can notice the “FF..” on the beginning, it means that there are two tests failing [F] an two passing [.].

Since it failed, it is time to write the code to make it pass. On the book model, add the validation for the mandatory fields, like this:

class Book < ActiveRecord::Base
  validates_presence_of [:title, :author]
end

Running the specs again show us that it worked:

....

Finished in 0.061223 seconds

4 examples, 0 failures

Homework: write tests to guarantee that duplicated titles are not allowed.

Now we need to add another test, describing our application. Let’s create the books controller, once again, we’re using the rspec generator

script/generate rspec_controller books

Go to the spec/controllers/books_controller_spec.rb and let’s write our test for the action “create”:

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe BooksController do
  it "should have an action that allow the creation of new books" do
    controller.should respond_to(:create)
  end
end

Ideally speaking, you will want to keep each “example” (the term rspec uses for each individual test) to the minimum assertions possible. That will make things more traceable later. Run the spec and watch it fail!

Now, time to write the minimum code necessary to make it pass, on the books controller:

def create
end

Run the specs again and see that its all green now.

Now we need to write another test, since clearly just having a method create on our books controller won’t do us any good. What’s missing is that the create method should receive the parameters to create a new book on the database and do it.

But this is a problematic point: if we write the test to actually persist our book on the database, we will be depending on book model logic again - which has already been tested somewhere else. This is not going to be a unit test at all, but a full stack one - which is bound to become slow pretty fast. Not to mention that if the controller tests depend on the model, and you screw up the model, the controller tests will also fail, totally ruining the traceability that your test suite should provide.

The solution for that is another widespread term: dependency injection. Any decent modern language have a whole bunch of frameworks for dependency injection a.k.a. inversion of control. What it means is that your implementation should be flexible enough to depend on the interface of its dependencies, not on their implementation. Putting it in simple terms, let’s say you’re programming an entity on C#, that depends on a repository for persistence, you should create an interface for this repository and have your entity provide some way of replacing the actual implementation with a fake one (mostly for the purpose of decoupled testing). But, since we’re working with ruby, and it has open classes, it is not even needed to bother with providing ways for dependency injection - just keep the concept in mind.

To properly make use of dependency injection, we need to setup fake implementation for the dependencies of our classes. Let’s look at our bookstore: the books controller depends on the book model, so we need to replace the model implementation on the controller with a fake one, that provides us with full control over it. What I’m talking about right now can be mainly categorized between two big concepts of unit testing: mocks and stubs. The difference between the two is very subtle on the first sight, so further reading about these two concepts is strongly advised. There are also some other important ones, like fakes and spies. But that isn’t needed for now, just try to get a grasp on their purpose in this practical example, continuing our bookstore:

describe BooksController, "creating a valid book" do
  before(:each) do
    @params_for_save = { "title" => "advanced joseki", "author" => "honinbou shusaku" }
    @book = mock_model(Book)
    Book.stub!(:new).and_return(@book)
  end

  def call_create
    post :create, { :book => @params_for_save }
  end

  it "should instantiate a new book with the given parameters" do
    Book.should_receive(:new).with(@params_for_save).and_return(@book)
    call_create
  end
end

One thing at a time, let’s look ath the “before each” method first:

  • @params_for_save is just a helper to avoid repetition of the same hash of parameters over and over and over again
  • @book represents a mocked instance of the book model - we’ll see more about this later on
  • Book.stub! says that the Book (app/model/Book.rb) class will be replaced with this stub. When the method “new” is called, this stub will return our mocked book, instead of creating a new instance

What we gained from that? Let’s say the “new” (initialize) method of the original book model does something like checking the database for some condition, or calling an webservice, or whatever… by replacing the Book class implementation with this stub, we’re totally decoupling our controller test from any of that. These aspects of the Book model should have been already tested elsewhere (on the specific Book model spec) - so we can just assume that they will work and focus on what we are testing right now: the controller.

The “call_create” is just a helper method, once again to avoid repetition. What it does is just simulate a post (like a form would do) to the create method, passing the parameters like if it was being passed by the real form.

The example says that in the method we are testing (create), the constructor of the Book class shall be called, passing the parameters received on the post request - and when it is called, it will return our mocked book model. Running the specs now will fail, because our “create” method isn’t calling the constructor of the Book class, as the example describes it should.

To fix that we must instantiate a new book on the controller.

@book = Book.new params[:book]

This will make the specs run successfully! So, time to ellaborate on our examples:

describe BooksController, "creating a valid book" do
  before(:each) do
    @params_for_save = { "title" => "advanced joseki", "author" => "honinbou shusaku" }
    @book = mock_model(Book, :save! => true)
    Book.stub!(:new).and_return(@book)
  end

  def call_create
    post :create, { :book => @params_for_save }
  end

  it "should instantiate a new book with the given parameters" do
    Book.should_receive(:new).with(@params_for_save).and_return(@book)
    call_create
  end

  it "should save the book on the database" do
    @book.should_receive(:save!).and_return(true)
    call_create
  end

  it "should notice the user about the success" do
    call_create
    flash.now[:notice].should match(/.*successfully.*/)
  end
end

Things to notice:

  • The mock_model call on the “before each” method has been slighly modified. That tells our mock that “save!” is a valid method, and when called it should return true. That means that when the controller calls it, during the test, it won’t actually save the book on the database, but just get a true return - just like the actuall Book would do if the save operation were successful
  • There were added two new examples, which I think shouldn’t be a problem to understand. I’ve added two at once for the sake of eliminating the repetition on this article - while developing you should write one test (example, whatever you call it) and watch it fail, make it pass, then write another one and so on… Keep that in mind, because from now on I will quicken up the pace

Running the specs it shall fail - then let’s make it pass:

class BooksController < ApplicationController
  def create
    @book = Book.new params[:book]
    @book.save!
    flash[:notice] = "The book was saved successfully"
    render :text => ""
  end
end

Running the specs now shall give you an all green result.

To wrap it up, let’s see how we can add a error scenario to our controller test - like an invalid book. It will probably look something like this:

describe BooksController, "creating an invalid new book" do
  before(:each) do
    @params_for_save = { "title" => "the god delusion", "author" => "richard dawkins" }
    Book.stub!(:new).and_return(@book = mock_model(Book, :save! => true))
  end

  def call_create
    post :create, { :book => @params_for_save }
  end

  it "should instantiate a new book with the given parameters" do
    Book.should_receive(:new).with(@params_for_save).and_return(@book)
    call_create
  end

  it "should notice the user that the book is invalid" do
    @book.should_receive(:save!).and_raise(StandardError.new("Error saving the book"))
    call_create
  end

  it "should notice the user about the failure" do
    @book.should_receive(:save!).and_raise(StandardError.new("Error saving the book"))
    call_create
    flash.now[:notice].should match(/.*error.*/)
  end
end

Notice how I said that I was going to use an invalid book but used the exact same (business-wise VALID) parameters? That’s the wonder of mocking and stubbing - the controller test doesn’t need to and shouldn’t [must not! if you're purist enough] know what is a valid book at all. It just needs to know how the controller should react given that the book model showed that it is not valid. Once again: the test to check if a book is been properly validated have already been tested on the model level specs.

So, let’s make the tests pass - shall we?

class BooksController < ApplicationController
  def create
    @book = Book.new params[:book]
    @book.save!
    flash[:notice] = "The book was saved successfully"
    render :text => ""
  rescue
    flash[:notice] = "There was an error saving the book"
    render :text => ""
  end
end

That will make all specs pass.

Notice that I didn’t mentioned anything about views - while rspec, not to mention the entire rails structure, gives you a pretty good support for testing them, I usually don’t do it on the unit test level [it probably is due to my lack of ability to do it properly, but the code simply tends to become really messy and not very readable]. So I try to leave it to cucumber.

As usual you can get the code used for this article on github. Please leave your impressions on the comments section.

BDD - Beyond the Buzzwords

Posted on July 24th, 2009 by macskeptic

This post is going to be the first of a series "Beyond The Buzzwords" of two (maybe three). This being a subject that has been getting some hype everywhere now doesn’t seem to be the kind of thing you would normally see here. We generally like to talk about the state of the art, and about things you can’t just google for - replicating knowledge like oh so many other blogs out there do, doesn’t particularly appeal to any of us.

But, since a great friend of mine asked for some very specific material about tests on rails, I decided to direct the effort to make something a little more presentable and put it here, so that anyone can benefit from it (and/or, most likely, criticize it).

Intro

Virtually any of us who ever worked with the whole PMI, CMMI overhead pestering the thinking process at each and every step might have found himself thinking something on the lines of: What the heck am I doing all this soon-to-be totally obsolete documentation for? How can I expect to know how the software will be written before starting to write it?

I know, the classic methodologies are not necessarily bad. They just tend to be really good for the mediocre minds, and really bad for the smart ones. Since there are a gazillion more of the first kind in this world we live on…

KaizenAs an answer to that sort of overly defensive mentality, came the agile manifesto. Ever since, agile methodologies and buzzwords have been popping up furiously each and everyday. The vast majority of them coming from the well known Toyota’s Kaizen mentality.

At the very core of any reliable agile culture for software development [alongside many other things] lies the love for testing. Testing early, testing often, testing all the fucking time. Yes, love, you really got to eager for it every second of your development cycle.

It is often said that very good programmers are not seldom very bad at testing, and they simply couldn’t hate any more than they do. My former self is a pretty good example of that - a lightning fast programmer, a good understating of design patterns and practices but, testing? If you asked me a year ago, I would have said: that’s work for some monkey, not ME. the UI is a sketchy prototype, but the game mechanics is rock solid already

But that was the old fashioned me, which was used to seeing manual testing, and thought actual automated testing was something that could only be seen on textbooks and academic projects. Once you get the grasp on the value and importance of testing, you just won’t be willing to ever do anything for serious without it. These days I find myself doing a test first approach for virtually anything that I truly wish to work - like the AI for a relatively simple board game I’m working with on my spare time right now.

Two of the most widespread terms for testing are BDD and TDD. I’ll be talking about these two on the two articles of this series - if the need arises I might even write a third to sum it up. This first article is all about BDD.

BDD stands for Behavior Driven Design (Development - nobody seems to know anymore which one is the right term, I use "Design" because I like it). This practice suggest a deeper relationship between the developers and the domain experts (your clients, most likely). The basic idea is to get both sides talking the same language so that they can, together, determine how the software that will be developed should behave.

To accomplish that, any framework that claims to be a tool for BDD shall provide a language that can be both understandable by only slightly technical people and programmatically viable to interpret on automated tests.

The ruby language holds one of the most remarkable of such frameworks out there: cucumber. For the next few paragraphs I will go through a very simple implementation of a bookstore (only the "add new book" functionality actually) using ruby on rails, from a BDD approach using cucumber.

If we were on an agile environment, most likely the development team would get a story to work on like this:

As the bookstore owner
I want to be able to register new titles to sell, including rating and synopsis
So that I can extend the list of products for sale without depending on manual intervention from the IT guys

After talking with the story owner, we decided that the relevant fields that a book entry should have are:

  • Title
  • Author
  • Rating
  • Synopsis

So now, let’s go to the fun part: code! [YATTA]

pre-reqs

To properly follow this series of articles you will most likely need the following (along with all their dependencies):

  • Ruby
  • Gem
  • Rails
  • Cucumber
  • MySQL
  • ZenTest (not for this article - but get it already!)
  • Rspec

For the installation process of the aforementioned requirements on your platform of choice you are on your own though. A simple google search will most likely get you there - don’t forget to also install all their pre-reqs. You should be able to follow the steps below on any OS - I’m particularly using Ubuntu with GMate (a bunch of customizations for GEdit) as the text editor.

I would strongly advice against trying it on any Windows platform though. Don’t get me wrong, I love Microsoft products, but ruby just don’t get along well with Windows, not to mention there are not a single text editor nor IDE that feel good to work with it on the platform [but that's only my personal opinion - there are always those kids that love netbeans…]. If you must [you shouldn't], try to at least go with JRuby, it runs way smoother than the one click installer ruby on Windows.

1

First things first, creating the application and the databases (using mysql because I’m too lazy to install sqlite on my ubuntu VM):

rails --database=mysql bookstore
cd bookstore
rake db:create:all
rake db:migrate

2

Adding cucumber support:

script/generate cucumber

This should generate some basic infrastructure for your application.

3

Writing the first feature:

gedit features/register_new_books.feature &

Here is where the fun will begin. Remember our story? We’re going to translate it to cucumber:

First the feature overview, it is just for the sake of documenting, so you can write it however you feel its best:

Feature: Register new books
In order to make my bookstore expansible
As a bookstore owner
I want to be able to register new books

Now, we’re going to use a scenario outline, to define how this specific feature should behave when used:

Scenario Outline: User register a new book successfully
Given I am on the new book register page
Then I should see "Title"
And I should see "Author"
And I should see "Rating"
And I should see "Synopsis"
When I fill in "book[title]" with "<book_title>"
And I fill in "book[author]" with "<book_author>"
And I fill in "book[rating]" with "<book_rating>"
And I fill in "book[synopsis]" with "<book_synopsis>"
And I press "Save"
Then I should not see "<book_title>"
And I should not see "<book_author>"
And I should not see "<book_rating>"
And I should not see "<book_synopsis>"
And I should see "successfully"
And the book with the title "<book_title>" should have been saved on the database

One very important point to get here, is that if you use the constructs "I should see __", "I fill in __ with __", "I press __" - these, alongside with a couple more are predefined steps that webrat provides you out of the box. You can check them all on the webrat_steps.rb file.

Please note that the <> enclosed strings are placeholders, so that one can execute that set of steps for multiple examples of actual data. Now, we need to define those examples, in a mostly intuitive way:

Examples:
| book_title          | book_rating | book_synopsis     | book_author         |
| the god delusion    | 9           | too soft          | richard dawkins     |
| the antichrist      | 9           | ubermesnch        | friedrich nietzsche |
| holy bible          | 0           | childish folklore | charlatans          |

4

Giving the feature it’s first go, just type:

rake features

The output should be a colorful (if you’re on a decent OS/Command Line/Bash):

Feature: Register new books
  In order to make my bookstore expansible
  As a bookstore owner
  I want to be able to register new books

  Scenario Outline: User register a new book successfully
    Given I am on the new book register page
    Then I should see "Title"
    And I should see "Author"
    And I should see "Rating"
    And I should see "Synopsis"
    When I fill in "book[title]" with "<book_title>:"
    And I fill in "book[author]" with "<book_author>:"
    And I fill in "book[rating]" with "<book_rating>:"
    And I fill in "book[synopsis]" with "<book_synopsis>:"
    And I press "Save"
    Then I should be on the new book register page
    And I should see "Title"
    And I should see "Rating"
    And I should see "Author"
    And I should see "Synopsis"
    And I should not see "<book_title>"
    And I should not see "<book_author>"
    And I should not see "<book_rating>"
    And I should not see "<book_synopsis>"
    And I should see "successfully"                    

    Examples:
      | book_title       | book_rating | book_synopsis  | book_author         |
CLUE  | the god delusion | 9           | too soft | richard dawkins     |
==>   Can't find mapping from "the new book register page" to a path.
==>   Now, go and add a mapping in
==>   /home/macskeptic/workspace/rails/bookstore/features/support/paths.rb (RuntimeError)
==>   /home/macskeptic/workspace/rails/bookstore/features/support/paths.rb:22:in `/^I am on (.+)$/'
CLUE  features/register_new_books.feature:7:in `Given I am on the new book register page'
      | the antichrist   | 9           | ubermesnch     | friedrich nietzsche |
      Can't find mapping from "the new book register page" to a path.
      Now, go and add a mapping in
      /home/macskeptic/workspace/rails/bookstore/features/support/paths.rb (RuntimeError)
      /home/macskeptic/workspace/rails/bookstore/features/support/paths.rb:22:in `/^I am on (.+)$/'
      features/register_new_books.feature:7:in `Given I am on the new book register page'
      | holy bible       | 0           | childish folklore    | charlatans          |
      Can't find mapping from "the new book register page" to a path.
      Now, go and add a mapping in
      /home/macskeptic/workspace/rails/bookstore/features/support/paths.rb (RuntimeError)
      /home/macskeptic/workspace/rails/bookstore/features/support/paths.rb:22:in `/^I am on (.+)$/'
      features/register_new_books.feature:7:in `Given I am on the new book register page'

3 scenarios (3 failed)
60 steps (3 failed, 57 skipped)

As you can see, it failed, since we got nothing on our application yet, just the feature specification. But it gave us a clue about what to do next, as I pointed above.

The phrase above is a very interesting concept - you write about the expected behavior before doing anything related to the code that will make it happen.

5

Since it said there is no "the new book register page" path, we’re going to add it, so that we solve the current problem and then we can try running the feature once again:

gedit features/support/paths.rb &

Here we will just define the missing path, adding something like this:

when /the new book register page/
'/books/new'

6

Running the feature again changes the error:

No route matches "/books/new" with {:method=>:get} (ActionController::RoutingError)
(eval):2:in `/^I am on (.+)$/'
features/register_new_books.feature:7:in `Given I am on the new book register page'

Once again, the error gives us a pretty nice hint about what to do next.

7

We need a route that matches books/new… that is a controller for books, with a method called new, so on to id:

gedit app/controllers/books_controller.rb &

Adding the method that should look something like this:

class BooksController < ApplicationController

def new
render :text => ""
end

end

I’ve chosen to render an empty text so that it won’t complain about there is no template yet.

8

Running the feature again changes the error:

expected the following element's content to include "Title":
(Spec::Expectations::ExpectationNotMetError)
features/register_new_books.feature:8:in `Then I should see "Title"'

3 scenarios (3 failed)
60 steps (3 failed, 54 skipped, 3 passed)

Could this error messages be any more helpful? I doubt it!

9

Since the last executing told us that "Title" could not be seen on the page, we will do the bare minimum code necessary to make it happy. Normally I would suggest that you do it for each term on the page (Title, Author, Synopsis and Rating), but for the sake of succinctness I will do the four on a single step (try not to do things like that if you’re beginning to adopt BDD just now, keep the steps SIMPLE, ridiculously SIMPLE)

Here:

gedit app/controllers/books_controller.rb &

We will change the rendering to:

render :text => "Title Synopsis Author Rating"

Remember: do only the bare minimum so that the current step can be successful.

10

Running the feature again changes the error:

Could not find field: "book[title]" (Webrat::NotFoundError)
(eval):2:in `/^I fill in "([^\"]*)" with "([^\"]*)"$/'
features/register_new_books.feature:12:in `When I fill in "book[title]" with "<book_title>"'

3 scenarios (3 failed)
60 steps (3 failed, 42 skipped, 15 passed)

We’re getting better, 5 steps passed already for each execution of the scenario outline (since we have 3 examples, 15 steps overall).

I guess you’re getting the grasp about what to do next, right? Hence and repeat…

11

Since the current step wants to fill some field on the page, we will most likely not find a way to implement it without creating a template.

We could create a pure HTML template, that would most likely be the best approach here, theoretically speaking - but once again, I have no intent of forcing a purist mentality over other people. You shall choose how much leeway you want to give to your steps, but keep in mind that you should always try your utmost to keep it to the minimum.

Since I’m planning to already use rails helpers to create a form for a model, I will need a model at this point. It is already too much implementation for a single step!

That’s when you can see how BDD per se falls short, lacking on dept on implementation heavy tasks. I mean, your client will most likely care that when he access a link, a page is shown with a given set of characteristics and a given behavior. But certainly he couldn’t care less about what sort of classes, controllers, models or whatever else techie stuff you need to make it happen.

Therefore, here’s a pretty good point to introduce the importance of TDD, so that’s going to be the main entry point of the next article. For now, please just put a bookmark here on your mind and bear with the inadequately huge implementation for this step.

Creating the view:

gedit app/views/books/new.html.erb &

Something like this:

<% form_for @book, :url => { :action => 'create' } do |f| -%>
<% field_set_tag 'New Book' do -%>
<p>
<%= f.label 'title'%><br />
<%= f.text_field 'title'%>
</p>
<p>
<%= f.label 'author'%><br />
<%= f.text_field 'author'%>
</p>
<p>
<%= f.label 'rating'%><br />
<%= f.text_field 'rating'%>
</p>
<p>
<%= f.label 'synopsis'%><br />
<%= f.text_area 'synopsis'%>
</p>
<p>
<%= f.submit 'Save' %>
</p>
<% end -%>
<% end -%>

Creating the model:

script/generate model book title:string author:string rating:decimal synopsis:text
rake db:migrate

Adapting the controller to use the view:

gedit app/controllers/books_controller.rb &

It will probably look like this now:

def new
@book = Book.new
end

12

Running the feature changes the error:

No action responded to create. Actions: new (ActionController::UnknownAction)
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
(eval):2:in `/^I press "([^\"]*)"$/'
features/register_new_books.feature:16:in `And I press "Save"'

3 scenarios (3 failed)
48 steps (3 failed, 18 skipped, 27 passed)

As you can see, the data input was successful - now we are stuck to the save button functionality, it redirects to the create action, which doesn’t exist as of now. So, you know what to do.

13

Adapting the controller:

gedit app/controllers/books_controller.rb &

With the simplest implementation possible to make the step pass:

def create
render :text => ""
end

Running the feature again should give an error about the word "successfully" not being present on the screen after clicking save.

So, let’s fix it:

def create
render :text => "successfully"
end

14

Running the feature again tells us that we don’t know yet what it means to the book to be on the database:

TODO (Cucumber::Pending)
features/register_new_books.feature:22:in `And the book with the title "<book_title>" should have been saved on the database'

3 scenarios (3 pending)
48 steps (3 pending, 45 passed)

15

So, we need to tell it, how to check if the book was saved on the database:

gedit features/step_definitions/book_steps.rb &

Here we will define a step, like this:

Then /the book with the title "([^\"]*)" should have been saved on the database/ do |book_title|
Book.find_by_title(book_title).should_not be_nil
end

The code above should be self explanatory by just reading it out loud, we will get into more details about this on the next post.

The regular expression will be matched against the steps on your feature description. Also, to make the assertion I’m using the rspec synthax - don’t worry about it right now, I’ll get into more details about it on the next article, since it is more directed to the TDD practice.

Here I shall give some more "do what I tell you, not what my shown code does" kind of talk: It is quite questionable to put such low level assertion on a feature. Your client might not even know what a database is. And the feature’s intent is to be readable and discussable by him too. So, there would probably be a lot better to go to the book listing page and check if your book is there as an assertion that it has been saved indeed.

Why I didn’t do that? Because I’m lazy and didn’t want to implement the listing page, and the few more steps needed to make the assertion - but that can be considered mandatory homework for you ;).

16

Now that cucumber knows what it means to check if the book has been saved to the database, when we run the feature again we get:

expected nil? to return false, got true (Spec::Expectations::ExpectationNotMetError)
features/register_new_books.feature:22:in `And the book with the title "<book_title>" should have been saved on the database'

3 scenarios (3 failed)
48 steps (3 failed, 45 passed)

That means, the book is not on the database.

17

So, what is left is to change the create action to actually do something:

gedit app/controllers/books_controller.rb &

Something like this will do the trick:

def create
Book.create(params[:book])
render :text => "successfully"
end

I know, you should check for errors and all that stuff - just don’t focus on the implementation I’m giving you (which is as succinct as possible, so that it fits better to be put inline here on codevil), but on the bigger picture concept behind it all.

18

Now, what is left is run the feature one last time, and rejoice:

Feature: Register new books
  In order to make my bookstore expansible
  As a bookstore owner
  I want to be able to register new books

  Scenario Outline: User register a new book successfully
    Given I am on the new book register page
    Then I should see "Title"
    And I should see "Author"
    And I should see "Rating"
    And I should see "Synopsis"
    When I fill in "book[title]" with ""
    And I fill in "book[author]" with ""
    And I fill in "book[rating]" with ""
    And I fill in "book[synopsis]" with ""
    And I press "Save"
    Then I should not see "<book_title>"
    And I should not see "<book_author>"
    And I should not see "<book_rating>"
    And I should not see "<book_synopsis>"
    And I should see "successfully"
    And the book with the title "<book_title>" should have been saved on the database

    Examples:
      | book_title       | book_rating | book_synopsis     | book_author         |
      | the god delusion | 9           | too soft          | richard dawkins     |
      | the antichrist   | 9           | ubermesnch        | friedrich nietzsche |
      | holy bible       | 0           | childish folklore | charlatans          |

3 scenarios (3 passed)
48 steps (48 passed)

Finally, all steps passing successfully.

END

That concludes this first article, I hope it has been of use to you guys beginning to do automated tests. As usual, you can download the full code used in this example at my github.

Please leave your impressions on the comments section.

Recommended [very short] reading: http://dannorth.net/introducing-bdd

The Repository Pattern

Posted on July 2nd, 2009 by macskeptic

Today’s post is about more than a simple punctual matter that I’ve come across at some moment in my day to day activities or on my restless nights of endless hacking.

Despise my overall remarkable programmer geekiness, I am first and foremost a philosopher. As a consequence to that, I love to I/O - big essays - so if you want to skip the background story and get right into the fun part, just jump straight to last tab below, ok? If you want to be even more hasty, you can go straight to the github project page and check it out there.

Historical Motivation

Historical Motivation

I’ve been doing software for about 5 years now - be it professionally or academically. My first professional endeavor dates from early 2005, a freelance in PHP while I was still coursing the Computer Science Bachelor degree at UFSCar. Professionally, I’ve had two years at Accenture, doing mainly Java and Pro*C projects, and now I’m moving pretty fast for completing a year (on October) at Locaweb.

In all that very short timed but very diversified experience, one major concern (maybe even the biggest concern of all) that often showed up while developing software is what kind of persistence engine the application will make use of. The vast majority of real world applications you will see out there uses a relational database (name it: Oracle, SQL Server, MySQL or whatever else) as its main persistence engine. Even if I try to remember, I can barely recall half a dozen applications that I worked with which didn’t use relational databases (one good example of these exceptions would be LDAP authentication applications - although even those might end up using some relational back-end).

Given that, how you will deal with your persistence engine should be one of the top priorities on your design plan for virtually any application. A bad choice on this matter might very easily lead to catastrophic results, no matter how good the rest of the overall design is. Since the software development niche is a wide boundless world, it should be expected that such a crucial concern has some good and fairly established frameworks to deal with it. And there surely are, quite a bunch indeed - if you pick a widespread popular language like Java, it even becomes a pain to decide amidst of so many options.

[Be advised that this specific paragraph below is a very outdated opinion (I don't do drug… erm Java anymore)]
At Accenture I’ve worked a little bit with two of the most widely accepted Java options out there: Hibernate and Spring (there’s also JPA, but I’ve never tried it). But, none of these seemed to be very pleasant to work with [reinforcing - that was the situation two years ago] - specially in a situation when you have no control over the database, it is just there, and you have to live with it. There was tons of configuration, tons of giving up some control of what is being done by the application to the framework. That last part always sounded pretty bad, specially in the kind of project I was working on: tons of data, where if a select took one millisecond more than necessary to complete, it would sum up over the iterations, making a huge difference (sometimes hours) on the final execution time. So, for me that was always a no go.

Since I’ve seen the idea of Active Record for the first time while studying Ruby on Rails last year (I’ve heard that you can do something quite similar with the latest versions of Hibernate too), I’ve been in love with the idea. No pollution in your model, no endless configuration, straightforward persistence on the fly. Seems to good to be true. And actually it is, it won’t solve half of any real business application persistence problem. If you have a beautiful database, with ID’s in all tables, and good, ubiquitous naming conventions - you’re good. But, just how many real world business projects can say that their databases are like that? Most of today’s software was written quite a while ago, with those big badass monolithic databases - with tables and columns using the legendary Hungarian notation and all that. In those cases, you’re back to endless configuration hell. I’ve put together a very quick "hello world" with the castle implementation of Active Record for C#, using NHibernate as a back-end and it seemed to work fine, although falling into the same problems aforementioned.

One very common saying amongst fellow developers is that "there is no silver bullet" in this activity. That means, no absolute rule, no solve-all-your-problems idea. But, I would say that although there are no such things that can guarantee your success, there are certainly those ones that you should not do. One of those things that in almost any case will most likely result in catastrophic failure is: never, ever, fight your framework.

That’s basically the background story and historical motivation behind the whole idea that will be shown in the following (many) paragraphs.

Understanding the Repository pattern

Understanding the Repository pattern

For each type of object that needs global access, create an object that can provide the
illusion of an in-memory collection of all objects of that type. Set up access through a
well-known global interface. Provide methods to add and remove objects, which will
encapsulate the actual insertion or removal of data in the data store. Provide methods
that select objects based on some criteria and return fully instantiated objects or
collections of objects whose attribute values meet the criteria, thereby encapsulating
the actual storage and query technology (…)

Evans, Eric (2003) Domain Driven Design - Tackling Complexity in the Heart of Software

The above quotation gives an overview of the main concept of the responsibility attributed to the repository pattern. Oversimplifying maybe, a repository is a mechanism of dealing with the lifecycle of an entity (or aggregate root) - providing a clear, centralized interface to access, modify, or destroy it.

One of the main reasons to use a repository is to clearly decouple the persistence logic from the model and application layers. A repository isn’t a DAO, it contains business logic of how each type of object in your model can be dealt with, it might even use a DAO implementation behind the scenes to do the actual queries. It also will most likely make use of factories to create the fully instantiated entities, once the necessary data has been retrieved from the database.

Henceforth, while developing the application and model layers, the developer can focus his energy on the domain itself, since the entire persistence concern has been delegated to the repositories.

Any big enough application in which you are not planning on using a full fledged persistence framework will most likely have some sort of implementation of a repository. Otherwise the domain would be very polluted with infra-structure and persistence logic. So, the idea here is to show an implementation of this pattern that is been working quite well for us in a real business scenario - since it might help other people too, if they happen to be working on a similar platform.

Implementing the Repository

Implementing the Repository

Okay, this is going to be very specific. On our current projects, for various reasons, we’re using the following platform:

  • Language: Microsoft .NET Framework 3.5 SP1 (C#)
  • Database: Microsoft SQL Server 2005
  • IDE: Microsoft Visual Studio 2008 Team System
  • Source Control: Git

On a given point during a sprint a couple of months ago, one of my teammates (kitaly) came up with an example of a repository implementation which seemed to be going to a very interesting direction. So, on our first all new project after that, we’ve decided to try and check it out if we could make it work for our business scenario.

The main idea was to provide the methods: "save", "find" and "delete". To gain that, each specific repository would have to implement as few as possible methods, for data mapping, generating custom fields and eventually logic for business access constraints.

Even if our brand new application had a pretty good expertly crafted database, some parts of it still had to deal with the legacy tables. So, we’ve chosen to go with LINQ to SQL, since it is very close to doing pure SQL (but not quite), and gave us all the flexibility (and customizability for performance) we shall need. After a incredibly productive and rather enjoyable session of massive brainstorming we’ve managed to do a working demo.

After being amused for its elegant and succinct implementation and seeing it working well on production environment, I’ve decided to dedicate some time to improve it even more, providing more functionality "out of the box", therefore requiring less code on each specific repository.

There is, although, a slightly upsetting tradeoff we had to take while developing the repository. Since LINQ relies on expressions going straight to queries, we’ve decided to expose the actual auto built DTO objects from LINQ’s data context. The problem here is that we broke one of the main tenants of the repository pattern: decoupling with the database. What we gained though was tons of flexibility and quite less code if we think what the same functionality would take if it was done using some sort of query object implementation. After all, programming is just about trade offs, and picking the ones that are better for your specific case. That’s why technical books can never be read as recipes, but sources of knowledge base.

Enough with small talk, time to see some actual code. Please note that I won’t post written code here (just pictures, since they are a lot easier to manage) - but don’t worry, you can download the entire solution on github, which includes the repository implementation and an extra project with a very easy to get example of usage.

For the forthcoming sections I’ll assume you have a good understanding of the C# language, its functional constructs, lambda expressions, and template (aka Generics) implementations - besides solid OO concepts, of course.

The heart of this repository implementation is its main interface:

image

The idea here is pretty simple:

  • Call "Find" passing an expression to get whichever entries you want. Note that you are going to refer to the DTO on the expression, but you are going to get a list of your model given entity or aggregate root. For the sake of keeping the repository’s client code as simple as possible, there are methods to find a list of records and a single specific record. If you try to call "FindSingle" with a condition that matches more than one entry on your database an exception will be thrown.
  • Call "Save" passing an entity to persist it. If it isn’t already on the database, it’s going to be created, otherwise the existing entry will be updated. Note that you can also pass an optional transaction to control transactions - in this case, the operation will occur inside the transaction, and you can commit or rollback it later.
  • Call "Delete" to remove an entity from the database. Note that similarly to the "Save" method, you can pass an optional transaction to handle transactions.
  • The repository is defined using two template parameters (I know it should be called Generics in C#, but I got so used to call it Template back in the C++ days…): the "TRow" should be mapped to a LINQ DTO, while the "TEntity" should be mapped to an entity of your model.

The repository project defines a basic abstract implementation of this interface, so that, if you have a decent enough database (each entity mapped to a table) you gain some pretty nice functionality out of the box. I’m not going to get into the details of the basic repository implementation since it’s meant to just be used as is.

What’s next is an example of what you would need to do to create a repository specific for one of the entities on your model:

imageI Believe that the "BeforeSave" and "AfterSave" methods should be self explanatory. But the "FindEntity" probably is not - the idea behind it is to establish a way to find the specific record that represents an in memory model entity on the database - so that the "Save" and "Delete" template methods can do their jobs.

An example of how to actually use the repository shall be worth a couple thousand words, so there it goes: imagePlease note that the code shown above is just for the sake of exemplifying what can be accomplished with the proposed repository implementation - I mean, don’t ever write unit tests like that on your projects, each unit test should test one specific piece of functionality.

And that’s pretty much it, feel free to download the source code on github and check the whole sample usage project (including all the snippets used in this article).

Feel free to criticize and leave your remarks on the commentaries - we’d love to hear your opinion.

Bizarre Visual Studio 2008 Error Message

Posted on June 10th, 2009 by macskeptic

This remembers me of the good ol’ crazy nonsense errors from Oracle:


CATASTROPHIC failure

The screen is all blurred to maintain privacy because that’s my work PC.

I’ve got this pretty awesome message by trying to save a file during a build. That’s the kind of thing that makes a programmer day.

Another credit card validator code

Posted on June 7th, 2009 by Koiti Takahashi

For the last few weeks, I’ve been working with PayPal API at my job. Besides the usual PayPal payment method, PayPal provides a direct credit card transaction solution too and it’s named Website Payments Pro. When we’re dealing with credit card numbers, we should be careful with fraudulent, illegal and false number cards. In my past experience, I’ve seen some credit card validators but never worried about how it was done. But this time, I had to take a look on how the validator works because of Discover credit card, which is not in use in Brazil.

A very quick search in the internet and I found the base algorithm to validate the most common credit card brands (Visa, MasterCard, Diners Club, Amex and Discover). It is the Luhn Algorithm. The Luhn Algorithm doubles every second digit from the rightmost of the provided number. For instance, if we have a number 529126, it will double the bolded digits. Then, it sums the doubled digits and undoubled digits ( (5×2) + 2 + (9×2) + 1 + (2×2) + 6) = 10 + 2 + 18 + 1 + 4 + 6 = (1 + 0) + 2 + (1 + 8 ) + 1 + 4 + 6 = 23 ). At last, it will verify if the resulted number is a multiple of 10.

So, let’s run into the code. The Luhn Algorithm implemented by me looks like the following:

public static bool LuhnAlgorithm(string creditCardNumber)
{
    bool alt = false;
    int sum = 0;

    if (String.IsNullOrEmpty(creditCardNumber))
    {
        throw new ArgumentNullException("creditCardNumber", String.Format(CultureInfo.CurrentCulture, "the credit card number can't be null!"));
    }

    if (!Regex.IsMatch(creditCardNumber, @"^\d*$"))
    {
        throw new ArgumentException("Invalid Credit Card Number", "creditCardNumber");
    }

    foreach (char digit in Reverse(creditCardNumber))
    {
        int digitToSum = int.Parse(digit.ToString());
        if (alt)
        {
            digitToSum = digitToSum * 2;
            if (digitToSum > 9)
            {
                digitToSum -= 9;
            }
        }

        sum += digitToSum;
        alt = !alt;
    }

    return (sum % 10 == 0);
}

The Reverse method is:

public static string Reverse(string s)
{
    char[] charArray = s.ToCharArray();
    Array.Reverse(charArray);
    return new string(charArray);
}

Now that we have the credit card number validator, we should check if the number is valid for the provided brand. To accomplish this task, we will use Regular Expressions. The table below shows how each brand implements their credit card numbers:

Card Type Prefix Length Regular Expression
AMEX 34, 37 15 ^3[4, 7][\d]{13}$
MASTERCARD 51-55 16 ^5[1-5][\d]{14}$
DINERS 300-305
36, 38
14 ^30[0-5][\d]{11}$
^3[6,8][\d]{12}$
DISCOVER 6011 16 ^6011[\d]{12}$
VISA 4 13
16
^4[\d]{12}$
^4[\d]{15}$

And that’s it. Just validates the credit card string number with the regular expression after the Luhn Algorithm and you will have a reliable credit card validator. The complete method will be like this:

public static bool ValidateCreditCardNumber(string creditCardNumber, string creditCardType)
{
    if (!LuhnAlgorithm(creditCardNumber))
    {
        return false;
    }

    switch (creditCardType)
    {
        case "visa":
            return ValidateVisa(creditCardNumber);
        case "masterCard":
            return ValidateMasterCard(creditCardNumber);
        case "diners":
            return ValidateDinersClub(creditCardNumber);
        case "amex":
            return ValidateAmex(creditCardNumber);
        case "discover":
            return ValidateDiscover(creditCardNumber);
        default:
            return false;
    }
}

The discover validator method:

public static bool ValidateDiscover(string creditCardNumber)
{
    return (Regex.IsMatch(creditCardNumber, @"^6011[\d]{12}$"));
}

setting app.config for different environments

Posted on May 28th, 2009 by Koiti Takahashi

Imagine the following scenario: You have a project that you just developed in your local machine and want to deploy it into the CI (Continuous Integration) and approval environments. In this project, there is a configuration file (app.config) that contains a few settings, for instance, connection strings and log file directory.

Quite common isn’t it? So, how do you handle with the annoying issue of changing your app.config file for all these environments?

Editing the configuration file in each environment doesn’t seem to be a smart solution. During the development, we can add further settings into the app.config. Updating the config file later (during the deployment) for every environment is a hard and unreliable manner to do this because we can miss some changes.

Another choice that I’ve seen consists in having a copy in your project for each environment. Well, this is much better. We will have app.config, app.config.ci, app.config.approval and app.config.production to satisfy our environments. So, whenever we need to add or change any settings, we can edit all these config files during the development phase. To deploy, just rename the correct file to app.config and that’s it. But the problem that I see in this solution is that our SCM will run crazy with all the renamings.

For example: rename app.config to app.config.local and app.config.ci to app.config. SCM will tell you that app.config has been modified, app.config.local has been created and app.config.ci has been deleted. What a mess!

Another issue of this solution is that it doesn’t help us when we want automatated deployment. It depends on manual editing of the config files or a dependency on a script to do the job.

To avoid these painful processes, we can use the project’s configurations and after build tasks set in .csproj file. I will explain in the following steps:

1st Step

1st Step

As default, Visual Studio creates two project configurations: Debug and Release. We’re going to add a configuration for each environment, assuming that both default configurations applies to our local environment. So, let’s create CI, Approval and Production configurations.

  1. In your Visual Studio, go to the “Solution Configurations” combobox and click “Configuration Manager…”
  2. In “Active solution configuration” combo box select “<New…>”
  3. In the popup window, fill the “Name” field with your environment name and select Release in “Copy settings from” combobox. Check “Create new project configurations” if it is not checked.
  4. Repeat this process for all environments.

At the end, you should have something like this:

Set of solution configurations

2nd Step

2nd Step

Next, let’s create the copies of our App.config files. For this, we will name all the copies as {Configuration}.config. So, in my example, I’ll have Approval.config, CI.config, Production.config.

App.config copies

Let’s change the connection string values from the files.

App.config settings:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="applicationConnection" connectionString="Data Source=localServer..." />
  </connectionStrings>
</configuration>

Approval.config settings:

<configuration>
  <connectionStrings>
    <add name="applicationConnection" connectionString="Data Source=approvalServer..." />
  </connectionStrings>
</configuration>

CI.config settings:

<configuration>
  <connectionStrings>
    <add name="applicationConnection" connectionString="Data Source=ciServer..." />
  </connectionStrings>
</configuration>

Production.config settings:

<configuration>
  <connectionStrings>
    <add name="applicationConnection" connectionString="Data Source=productionServer..." />
  </connectionStrings>
</configuration>

3rd Step

3rd Step

Finally, we will edit the .csproj file to add the AfterBuild task to replace the App.config file according to the configuration set on the build.

  1. Right click in your project and select “Unload Project”
  2. Right click “ProjectName(unavailable)” and select “Edit ProjectName.csproj”
  3. In the end of the file, add the next lines:

    <Target Name="AfterBuild" Condition="'$(Configuration)' == 'CI' or '$(Configuration)' == 'Production' or '$(Configuration)' == 'Approval' ">
        <Delete Files="$(TargetDir)$(TargetFileName).config" />
        <Copy SourceFiles="$(ProjectDir)$(Configuration).config" DestinationFiles="$(TargetDir)$(TargetFileName).config" />
    </Target>

Observe that these lines says: “After build, if configuration is ‘CI’ or ‘Production’ or ‘Approval’, delete output config file and copy {configuration}.config file into output file.”

After building using all configurations, you should have an output directory for each configuration in your bin folder. Check the config files and you should see the differences among them.

And that’s all! I hope you enjoyed this guide and starts to use it to build and deploy your projects with no worries regarding configuration files. C ya soon!

Posting and Getting files in ruby/rails

Posted on May 23rd, 2009 by macskeptic

Today I’m going to show some very short snippet about posting files with ruby, and receiving them in a rails controller.

For all examples I’ll be using the rest-client gem (”sudo gem install rest-client”).

The fist thing we’re going to do is to implement a very basic file post in ruby - there is basically two methods:

  1. You can post the contents of the file straight to the request body (I’m going to call it the “raw way”);
  2. You can pass the file contents as a parameter inside your request, like any other (I’m going to call it the “pretty way”).

One method is not necessarily better than the other, how you should do it depends a lot more on how your target service is implemented.

Posting a file, the “pretty way”:

PRETTY_UPLOAD = "http://localhost:3000/files/upload_pretty/pretty_file.txt"

def self.post
    pretty_resource = RestClient::Resource.new PRETTY_UPLOAD

    pretty_file = "./pretty_file.txt"

    File.open pretty_file, "wb" do |file|
      file.write "some random pretty content"
    end

    pretty_resource.post :file => File.read(pretty_file)
end

Posting a file, the “raw way”:

RAW_UPLOAD = "http://localhost:3000/files/upload_raw/raw_file.txt"

def self.post
    raw_resource = RestClient::Resource.new RAW_UPLOAD

    raw_file = "./raw_file.txt"

    File.open raw_file, "wb" do |file|
      file.write "some random raw content"
    end

    raw_resource.post File.read(raw_file)
end

Now, getting a file - since there is basically just one way to get it, I’ve made just one method - getting a file on ruby:

DOWNLOAD = "http://localhost:3000/files/download/raw_file.txt"

def self.get
    resource = RestClient::Resource.new DOWNLOAD

    downloaded_file = "./downloaded_file.txt"

    response = resource.get
    # you can access the headers (response.headers) or the
    # http response (response.net_http_res) if you need to

    File.open downloaded_file, "wb" do |file|
      file.write response.to_s
    end
end

That’s pretty much all you need on the client side (reading the contents of a regular http request should be no different at all than reading an attached file).

Time to go to the server side, shall we? Here good old rails kicks ass per se.

All I needed to do was to set up a custom route (just to make things more clear):

map.files ':controller/:action/:name.:extension'

Then, for the controller, I’ve set up two methods to receive the posted file - pay attention to the slightly different approach for the “pretty way” and the “raw way” of posting a file.

Receiving a file, the “pretty way”:

def upload_pretty
    file_name = "#{params[:name]}.#{params[:extension]}"
    file_contents = params[:file]
    File.open "tmp/#{file_name}", "wb" do |file|
      file.write file_contents
    end

    render :text => "ok"
end

Receiving a file, the “raw way”:

def upload_raw
    file_name = "#{params[:name]}.#{params[:extension]}"
    file_contents = request.raw_post
    File.open "tmp/#{file_name}", "wb" do |file|
      file.write file_contents
    end

    render :text => "ok"
end

I also provided a method for the client to download back the files, so that you can check on the contents to see that it went through flawlessly:

def download
    file_name = "#{params[:name]}.#{params[:extension]}"
    send_file "tmp/#{file_name}"
    # you can also use: send_data File.read("tmp/#{file_name}")
end

And that’s basically it, as simple as it can be.

As usual, you can download the sample code clicking here.

That’s a very quickly put together piece of code which, most likely, can be greatly improved - but I think it is just good enough to show the basics of how to get and post files on ruby and rails.

Criticism is always welcome.

CouchDB - Quick Tip

Posted on May 10th, 2009 by macskeptic

A quick tip for those who want to get a grasp on what CouchDB actually is before actually going to the trouble of setting up the whole environment (Erlang + CouchDB installation process seems to be a pain on Windows).

A friend of mine, who got all hyped about it when I told him about CouchDB sent me a link with an online interactive interpreter for people to toy with it. You can access it here.

To be able to actually do anything with it though, you’re going to need some knowledge of functional programming, specially map and reduce concepts.