Add the feature where you would like to find it

A new change or feature is about to be implemented. There are several places where it can fit in, and all of them seem to respect the Single Responsibility Principle. My tendency used to be adding the new feature where it was easier to place.  However now I consider other criterion. I ask myself this: If I need to navigate through the code base a bunch of months later to read the feature implementation... where would I look at in the first place?

Lesson: once you make sure your code is going to be SOLID, add the new feature in the place readers would expect to find it.

What methods should Value Objects contain?

Value objects can contain methods. Otherwise they are just anemic models. Those methods prevent the feature envy code smell and ease refactoring. They manipulate object internals promoting cohesion and low coupling. But don't forget about the Open/Closed principle. If you add that method to the object, is the code still open to extension without modification?

Imagine a value object encapsulating a collection. Now you need a method to sort the items in the collection. Should the "sort" method be part of the collection object? If is there a way to change the sorting algorithm without code modification, then the answer is yes. Otherwise the answer is no. Move the "sort" method to a specific class whose responsibility is sorting.

What would you expect the code to do?

Writing quality code is about satisfying the expectations of the reader. And the reader might be yourself a couple of months later.

Let me tell you a mistake a made recently. I was test-driving a few classes and one collaborator was a stack. But I only needed the stack to give me the last two items pushed on top of it.  So I ended up with a function like this:

  1. function pop(numberOfItems){
  2. // ... some code dealing with border cases...
  3. // and the happy path:
  4. return [items[len -1], items[len -2]];
  5. }

And everything went well. The stack was good enough for the object using it.
After a few months I needed to use the stack again but I forgot about its internals. I was writing some tests for a new class also depending on a stack. As the stack was already tested, I stubbed out the "pop" method in the new test pretending it could give me the last 3 items on the stack. The unit tests passed and my new class was working fine with the stack. However, it didn't work into production. Lesson:
Although TDD encourages you write only the smallest amount of code necessary to make the test pass, you should implement all the behavior a method is expected to have when someone reads its signature.

In one way or another I was coupling the stack to the class using it. But APIs should always tell the truth. Classes and methods should do what their name say without the need to know how other artifacts consume them.


Careful with JavaScript object literals

JavaScript object literals are very handy, they are just key-value pairs. Very convenient to implement dictionaries and also a very simple implementation of the Singleton pattern:

  1. var message = {sender: 'bob', body: 'hello'};

Duck typing is a technique I use very often as I test-drive my JavaScript code and object literals make it very easy. But overusing them lead to several problems:

I am no longer using object literals in my tests because when I need to add methods to those objects, I need to change too many tests. Also, exposing all those fields lead to feature envy rapidly, producing semantic coupling sooner or later. Although tests are written fast with object literals, I prefer to encapsulate the fields into business objects.

  2. function Message(sender, body){
  3. this.sender = sender;
  4. this.body = body;
  5. }
  6. var message = new Message();

Push the “how” down: Cukeup! 2013

It's been my first time attending to an event at Skills Matter and it's been awesome 😀

Cukeup! is the annual conference about BDD and Cucumber. This was the third edition.  Let me share with you the ideas I listened yesterday. The ideas and sentences written in here are not necessarily what speakers said, this is just my understanding of them. You can now view the talks online from the SkillsMatter site.

- Keynote by Aslak Hellesøy - father of Cucumber and coauthor of the excellent Cucumber book (which I recommend) and Cucumber Recipes (brand new):
Aslak told us how the development of Cucumber is going and the new design ideas they are working on, together with a review of the many flavors Cucumber's got. I missed a reference to SpecFlow in the slides though, as it is one of the tools I use and I think Gaspar Nagy is doing a great job (and he came to the conference by the way, which was nice). The thing I liked the most from this keynote was that he announced their new book recently published, Cucumber Recipes, which is now on top of my wishlist. And also the honest way he talked about the architecture redesign Cucumber needs and how are they approaching it. This is a good example of why architecture and design are so important.

- One-line step definitions with Matt Wynne - coauthor of the two books mentioned before:
You can see the talk online here (and so the others too). Having read his first book, the new ideas I got from this insightful talk was that the popular test pyramid can be "rotated". Matt and Seb Rose came across this idea together. Basically, you can use Cucumber to describe features without the need to access the application end to end, just exercising low level classes and methods from the step definitions. In those cases Seb decorates the features with tags indicating the level of abstraction they belong in (@without_ui for example). If you haven't read Matt's book, this talk is a good summary of some parts, it features some of the most important values and principles. Remarkable ideas:
Push the "how" down because it changes often and because it will not bring people into BDD as the features written in the imperative way are hard to understand and boring, cluttered with irrelevant information. Sometimes imperative style is the result of ignorance but it can also spot lack of trust in the team.  And... don't nest steps (call another step from the step definition).

- Working in the Cucumber World with Andrew Premdas:
Andrew's advise is to benefit from both, natural and programming languages when we write features and their step definitions. In order to do that, the "World" (fixtures used within step definitions) must be expressive, self-descriptiveAlthough he discouraged us from using global variables, there are some exceptions, something useful when referring to oneself in the fixtures is to use the variable "I" (@I in Ruby). Enrique Comba also suggested using @narrator (@ comes from Ruby) as the variable used to refer to the person telling the story. Because "narrator" might be clearer than "I" when there are many steps. Andrew said it was his first talk and he did very well in my opinion because clearly his primary concern was to communicate, so the message came out effectively.

- Don't you trust me? with Seb Rose:
Trust is easier to loose than to win. When developers tell testers that everything is fine but then it breaks, they are loosing points. Same when developers don't allow testers to navigate through the code base. Testers can work more effectively if they know a bit of programming and are able to check out the source code for inspection. When team members trust each other they clean up the road for others. Documenting high level architecture and components also helps.
Then he explained an experiment he is trying out: end to end tests are good to win trust so he starts by exercising the application like that from the features. But after that, he considers whether end to end is really the right way to go, because maybe exercising low level methods rather than several layers is cheaper, as long as there are already other end to end tests covering the path. Again, the rotated pyramid.

- The Impersonator Pattern with Enrique Comba:
Enrique got many of us thinking how to leverage the pattern right after his talk. He explained it on his blog time ago. A very nice secondary effect of this pattern, is that one can rapidly review the implementation of the impersonators and get a summary of what every persona in the project can do and what can't do. Useful documentation to have, specially when you have hundreds of features and thousands of steps. It was definitely a great talk, source of inspiration. His craftsman spirit lead him to this pattern as the consequence of following the "maximize code clarity" principle.

- Hands-on Cucumber.js with Julien Biezemans and Matt Wynne:
Julien, the creator or Cucumber's JavaScript flavor was pairing up with Matt to test-drive a little game live, writing the code directly in the browser with particular web environment set up by him. I am already using Cucumber.js so nothing new about that but I didn't know about uitest.js which they were using during the session. I am actually doing something similar on my own with Jasmine to run the app within an iframe so is good to know that more people are doing that. Some other times I just run cucumber.js from the command line using zombie.js.

 - Cross-platform BDD for Mobile with Karl Krukow:
Karl showed Calabash, a very powerful framework for mobile testing. Really impressive to me. It fits perfectly with hexagonal architecture and helps to avoid duplication in the tests while testing native apps on different mobiles platforms. It's really worth having a look at Calabash. I'll definitely will do. Of course the integration with Cucumber is excellent.

- Testing web apps with Cucumber.js with Paul Jensen:
Good speaker, nice technical stack and good ideas from the talk. He showed code from his successful app Dashku and its tests. I must say that the way I write JavaScript apps is different specially because I test-drive them whereas he showed a prototype developed without tests, having them added afterwards. But still, some good points in the talk.

Now I'll watch all the sessions that I couldn't attend to (haven't found the way to split myself in two). 

See you next year hopefully!