BDD: Executable Requirements

 

The problem

It doesn’t matter if your background is Agile, Iterative, Waterfall or Traditional. One thing is certain and we all agree: Excellent requirements combined with perfectly executed architecture is a great formula for success. At a first glance, the formula is simple… and it is! The problem is in the execution. How do we know we are being too heavy handed on requirements and design? In order words: how deep (or shallow) must the requirements be in order to be enough and how much design is needed for a perfect fit between business and technology?

The right amount of each ingredient of this formula has been haunting the development community since COBOL times and is still relevant in our Internet/Cloud/.Net/Java/Ruby/Python/PHP days… the mystery must be solved!

A solution

One solution to this dilemma can be found in agile methodologies. If you ask an agile methodologist the ingredient question, the answer will be, in most cases: avoid BDUF (Big Design Up Front). And it makes sense. One of the characteristics of requirements is that they tend to change. So if you take too much time in defining your requirements and architecture, as soon as you are ready to start implementing… guess what? Those pesky requirements decided to change!

So that’s a good start! Avoid BDUF! But that’s not a prescriptive approach, it’s restrictive. It’s great to know what we should NOT do. But what SHOULD we do? Well… again, agilists will say: TDD is the way, my brother … go forth and test first! Again… another great directive… and that’s very prescriptive… but is it complete? Hmmm… I’ll have to answer: no. Unfortunately, knowing that tests should be written before the actual implementation is part of the “path to perfection”. TDD is fantastic, I agree wholeheartedly. It practically forces the developer to write code using decoupled components. If the architecture follows industry-proven best practices, design patterns and good old common sense, it’s even better.  But one last question remains: WHAT should we test?

Do I see some hands raised in the audience? Oh, you, sir, please go ahead:

- Well, Daniel, of course. The answer is in the requirements. The developer should look up the requirements, understand the business need and design the tests accordingly.

Very well! That’s an excellent suggestion. But there’s a catch. It lies in the following word combination: “understand the business need”. Developers are, generally, a homogeneously Cartesian group of individuals. We live in a world of “0s” and “1s”, “Trues” and “Falses”, “ifs” and “elses”. Business level requirements may clearly identify a client need, but if they are not very carefully worded, ambiguity proliferates and the result may be like the age old, but too true “tire swing” cartoon.

Oh… and another catch: what about traceability? Which sentence of a classic requirement specification (set of) paragraphs traces to the code that needs to be reviewed whenever something changes? Tough, eh?

The solution

Well, several approaches to define unambiguous, verifiable, attainable and specific requirements have been subject of numerous papers, methodologies and frameworks. From now on, I’ll focus on a framework/methodology that has been working amazingly well in my experience: Behavior Driven Development (or BDD). BDD tries to bridge the gap between requirements analysts and developers by specifying a well defined “language”. This “language” is, at the same time, natural and specific. It is clearly understood by both business and technical-type stakeholders and describes system behavior. Here’s an example:

Feature: Order Placement	
  In order to purchase an item
  As a customer
  I want to be able to place orders


Scenario
: Add item to cart
 
Given
I have selected an item
 
And
I have provided its quantity
 
When
I press the "add to cart" button
 
Then
the item should be added to the cart
 
And the cart's total amount should be incremented by the selected item quantity multiplied by its price


It surely looks unambiguous, verifiable, attainable and specific enough, doesn’t it?



What if each one of those scenario lines became a specific step in a test case, from which architecture and code would be derived, a-la TDD? Wouldn’t it be fantastic? That’s exactly what BDD is about.



Next steps



I think this is just enough information to justify a couple of (near) future entries that will further clarify and exemplify BDD. Those entries will be a bit biased, though. Since my background is basically .Net, I will provide examples in C# using a beautifully implemented .Net-specific Cucumber-based BDD implementation: Specflow, an open source project sponsored by TechTalk.



See you in a bit!

Consumindo RESTful WebServices em C# com WCF e JSON (parte 1/2)

Introdução

Faz realmente muito tempo que não escrevo um artigo sobre desenvolvimento de sistemas mais técnico. Quem me conhece, sabe do meu passado bem próximo de linguagens como Pascal, Delphi, Java e C#. Já escrevi muitos artigos quando trabalhava na Borland, e alguns deles sobre WebServices. WebServices, lembram? Aquela tecnologia super moderna que permite a publicação e consumo de serviços e metadados (WSDL) via Web trafegando pacotes em XML? Pois é… super moderno não?

Na verdade, não. Apesar de se ainda suportar WebServices SOAP por aí, a tendência da Web 2.0 é a de se manter as coisas o mais simples e fáceis possíveis (KISS, entende?). Além disso, com o advento do AJAX e do browser como a plataforma cliente preferida da Web 2.0, o consumo de XMLs passou a ser uma coisa um pouco, por assim dizer, pesada para ser feita em AJAX, que normalmente faz uso de JavaScript.

Este conjunto de novos requisitos tecnológicos fez surgir dois novos “animais” magrinhos para a implementação de serviços via web, que estão rapidamente suplantando os WebServices SOAP convencionais (e gordinhos):

  • WebServices RESTful (versus SOAP-based)
  • JSON (versus XML)

Este é o primeiro de dois artigos que exploram as capacidades do WCF para comunicação com RESTFul WebServices e JSON.

WebServices RESTful

O protocolo SOAP é extremamente rico e cheio de funcionalidades. Via SOAP você consegue descrever objetos e mensagens de forma fortemente tipada, utilizando XML. Contudo, a infraestrutura para suporte a WebServices SOAP é bem pesada e, como já citei, pouco aderente a clientes “leves” como JavaScript rodando em um browser.

Com o objetivo de tornar a invocação de métodos remotos e de troca de dados um processo mais leve, surgiu o conceito de WebServices RESTful. Estes WebServices não seguem um protocolo complexo como o SOAP, mas devem seguir as características REST definidas por Roy T. Fielding. Basicamente, WebServices RESTFul são stateless e acessados a partir de operações HTTP padrão (GET, POST, PUT, DELETE) e retornam qualquer conteúdo (normalmente XML, JSON ou outro mime type).

Outra característica interessante desse tipo de WebServices é a de que a infraestrutura existente de servidores web pode ser utilizada, sem a necessidade de se incluir application servers, gateways, proxies, etc. (contudo, não há proibição de usá-los). O melhor é que servidores web existentes (Apache, IIS, etc.) suportam caching, autenticação, criptografia, etc.  sem grande necessidade de programação ou configuração, o que aumenta a performance e diminui a necessidade de recursos dos serviços.

JSON

Como uma alternativa ao XML, Douglas Crockford criou o JSON, que se tornou um RFC oficial (RFC 4627). A sua sintaxe é bem mais leve que o XML e é facilmente “parseavel” por qualquer linguagem de desenvolvimento. Baseia-se em um subset do JavaScript. Segue um exemplo de um bloco JSON:

  1: {"menu": {
  2:   "id": "file",
  3:   "value": "File",
  4:   "popup": {
  5:     "menuitem": [
  6:       {"value": "New", "onclick": "CreateNewDoc()"},
  7:       {"value": "Open", "onclick": "OpenDoc()"},
  8:       {"value": "Close", "onclick": "CloseDoc()"}
  9:     ]
 10:   }
 11: }}

WCF – Acessando a API do Twitter


Como exemplo de uso de WebServices RESTful com JSON, vou utilizar a api do Twitter, mais especificamente a chamada “statuses/public_timeline”.


Para começar, em seu Visual Studio 2008 ou Visual C# 2008 Express, crie um projeto Console.


Adicione referências aos assemblies abaixo:



  • System.ServiceModel.dll
  • System.ServiceModel.Web.dll

Ótimo! Estamos prontos para definir o contrato de dados


Definido o contrato de dados


Vamos utilizar o atributo DataContract para definir nosso “contrato de dados” com o serviço “statuses/public_timeline” em uma nova classe assim:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.ServiceModel;
  6: using System.Runtime.Serialization;
  7: 
  8: namespace TwitterClientPlayground
  9: {
 10:     [DataContract]
 11:     public class Status
 12:     {
 13:         [DataMember(Name = "text")]
 14:         public string text {get; set;}
 15: 
 16:         [DataContract]
 17:         public class User
 18:         {
 19:             [DataMember(Name = "screen_name")]
 20:             public string screenName {get; set;}
 21:         }
 22:         [DataMember (Name="user")]
 23:         public User user { get; set; }
 24: 
 25: 
 26:     }
 27: }

Você pode ver acima que a classe é uma classe C# como qualquer outra, com anotações em seus membros. A anotação “DataContract” define que a classe deve ser utilizada como contrato de dados pelo WCF. “DataMember” define membros do contrato de dados.


Uma questão interessante é que quando estamos utilizando uma “nested class”, esta também precisa ser marcada com “DataContract” (ver a classe “User” acima).


Definindo o contrato de serviço


O contrato de serviços é equivalente a um “stub” SOAP criado pelo “Add Web Reference” do IDE. Segue o nosso exemplo abaixo:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.ServiceModel;
  6: using System.ServiceModel.Web;
  7: 
  8: namespace TwitterClientPlayground
  9: {
 10:     [ServiceContract]
 11:     public interface ITwitterClient
 12:     {
 13:         [OperationContract]
 14:         [WebGet(
 15:             ResponseFormat = WebMessageFormat.Json,
 16:             UriTemplate="statuses/public_timeline.json"
 17:             )]
 18:         List<Status> Statuses_PublicTimeLine();
 19:     }
 20: }

O atributo “ServiceContract” define uma interface que irá ser utilizada pelo WCF como contrato de serviços entre o cliente e o servidor. “OperationContract” define uma operação e “WebGet” indica que a operação (método) será equivalente a uma chamada HTTP GET e permite que configuremos detalhes como o formato da resposta em ResponseFormat(no caso, JSON) e o fragmento da URI para acesso ao serviço em UriTemplate. A UriTemplate suporta parâmetros (entre chaves {}), que devem ter o mesmo nome do parâmetro do método sendo anotado, quando a operação do serviço assim o requerer. No caso, “statuses/public_timeline” não aceita parâmetros.


Conclusão


Por enquanto, neste artigo, procurei explicar os conceitos de WebServices RESTful e JSON, bem como a definição de contratos WCF para o consumo deste tipo de WebServices. No próximo artigo, iremos finalmente utilizar os contratos aqui definidos para efetuarmos chamadas ao WebService do Twitter.


Até lá!