Wednesday, March 30, 2011

The most popular technology for acceptance testing in Rails applications is Cucumber.

I used to be a big fan of Cucumber. We've been using it in every project for our customers.

From my point of view Cucumber delivers 2 important features:

A special language readable to non-programmers (Gherkin)

Acceptance tests - embedded browser driver - Webrat/Capybara etc

When I started using Cucumber (and prior to that I used Rspec Stories) it was mostly because of the acceptance tests part. Cucumber offered the whole philosophy in the framework, a philosophy based on the importance of communication with customers through the scenarios. The communication was based on a language called Gherkin.

Cucumber became a whole framework for managing requirements. The implementation is based on step definitions which we could implement in Ruby. Cucumber also gives us tools for running the acceptance tests, tools like tagging, features like documentation etc.

Thanks to tags we could run only the tests that are responsible for a specific part of the system. Another use case is to tag new scenarios with @wip and those are not run.

The biggest Cucumber project we have at the moment contains almost 600 scenarios. The biggest project I'm aware of has 2000 scenarios. It's a lot of "code".

With every new project I hoped that Cucumber can become one of the communication tools between our team and the customer. Only once I managed to get the customer write the scenarios, however the quality wasn't good and they had to be rewritten by a developer.

Every now and then we could send the scenario to the customer to get their approval that they are correct. In this cases the customer was able to read them easily. However, it was difficult to convince the customer to review the scenarios on a daily basis. They preferred writing a document or using a ticketing system like Redmine. The result is that we have requirements in 2 places - tickets and scenarios. It's not perfect, but it works well enough.

My conclusion for now is:

1. It's difficult to get the customer to write/read Cucumber scenarios

We gain a lot from the acceptance tests feature of Cucumber. Every functionality is covered by scenarios and it creates a nice regression weapon in cases where we need to change something in the application. Upgrading from Rails 2 to Rails 3 was one of such occasions. Unit tests would not be enough.

Recently I noticed that it's getting harder to manage the scenarios written the Cucumber way. There are many patterns how to keep the steps definitions, how to split the scenario etc.

I realized that it's the same kind of problem when you write a procedural code with no objects.

2. Cucumber scenarios most of the time are procedural programming.

With procedural programming it's hard to keep data and behaviour together. For simpler apps procedural programming is fine but for a bigger codebase I personally prefer object-oriented programing. I suppose it would be possible to include some object-orientation into Cucumber but I'm not sure if it would feel right and if it's worth the effort.

Summary

I see two problems with Cucumber and its usage in our projects:
It's hard to get customer working with scenarios and it's hard for developers to work with a bigger Cucumber codebase.

If you have customers working with Cucumber - congratulations! If you manage to deal with the procedural style of Cucumber - congratulations!

Is there any solution?

I started experimenting with a new way of acceptance testing based on Capybara and an object-oriented approach. It spread very quickly among the Wrocław Rails developers so it seems to be an idea worth investigating. I will present how it works in my next blog post. Stay tuned.

Friday, March 25, 2011

Here's my Euruko 2011 talk proposal which was rejected by the organizers. Let me know if the topic sounds interesting to you, I'd be happy to present it at some other conference.

Euruko 2011 talk proposal

It's a result of many years of my research/practice in OOP and MVC. The recent discovery of DCI can change a lot about the way we create MVC applications and Ruby is the best fit for DCI, in my opinion.

"MVC and OOP, are we doing our best?"

Ruby is one of the best OOP languages - are we using it the best way in our MVC applications? My observations show that there are common places where Ruby developers break the traditional OOP rules like the Law of Demeter or SOLID. It results in code of worse quality than it could be.

Early on, we agreed that we should move the logic from controllers into models. It's all fine, but most often it results in fat model classes. How to deal with the complexity?

DCI (Data Context Interactions), a new architecture paradigm focuses more on object behavior and fits very well with Ruby MVC frameworks like Rails or Sinatra. I will talk about DCI and present some examples. DCI was invented by Trygve Reenskaug, the same scientists who formulated MVC. One of its main ideas is to inject roles to objects runtime (using mixins), thus making the base classes much thiner.

DCI brings some fresh air into the MVC architecture and solves many of the existing problems, like:
- fat model classes
- difficult reusability
- testing problems
- instead of one big object-oriented design we can deal with many small ones

This talk is based on several of my blog posts. Some of the ideas were already presented at SRUG and DRUG (Silesia and Lower Silesia Ruby User Groups) meetups. The blog posts and the talks triggered many interesting discussions.

Andrzej Krzywda is the founder of Arkency, a Ruby on Rails shop (6 developers) based in Wroclaw, Poland. He also teaches Ruby on Rails at the University of Wroclaw. Andrzej has 11 years of IT experience. He has been involved in many different projects, including big telco, small startups, consulting companies etc. He worked with Java, .Net, Python, PHP but since 2004 he feels most comfortable with Ruby. Andrzej has presented at conferences like RuPy 2007, RuPy 2008, PyCon 2008, SFI 2006, SFI 2008, KKIO 2004 and lots of smaller meetups like DRUG or SRUG.andrzejkrzywda@gmail.com