Ruby on Rails, TDD et développement en top-down

Vous avez entendu parler du TDD, vous souhaiteriez l’appliquer mais il faut un début à tout.
Par où commencer ? Quel process suivre quand on développe une application rails ?

Voyons donc ce que le bon vieux “rails generate controller” nous mâche comme travail ou plutôt, comment maîtriser le processus de génération.

Je vous propose de réaliser en TDD l’équivalent de cette commande pour réaliser l’objectif suivant: “Je souhaite avoir une page affichant une liste d’événements”

Et comme il faut bien commencer, commençons par un bon…

rails new

“J’ai donc besoin d’une page contenant la liste des événements”

Test d’acceptation: Si je tape l’url de ma liste dans mon navigateur, je devrais voir quelquechose. Test Browser: En allant à cette URL, j’obtiens une page d’erreur 404 !

Il s’agit d’une de liste d’événements et c’est tout ce dont j’aurai besoin. Nous aurons donc en premier lieu besoin d’une URL, d’une route pour afficher notre résultat.

match ‘events/index’ => ‘events#index’, :via => :get

Créons donc la vue qui accueillera cette liste, le controller associé et bien évidemment, le fichier de test de ce controller. Fichiers crées:

app/views/events/index.html.erb
app/controllers/events_controller.rb
spec/controllers/events_controller_spec.rb

Dans un premier temps, remplissons notre vue d’événements fakes.

    Event 1
    Event 2
    …
    Event n

Pour que mon test d’acceptation soit complet, notre premier test devra donc vérifier que mon URL réponde.

describe EventController do
  describe 'get index' do
    it 'works' do
      get :index
      response.should be_success
    end
end

Rake spec: NoMethodError, indeed !
Test Browser: En allant à cette URL, j’obtiens toujours une page d’erreur 404 !

Codons donc la fonctionnalité:

class EventController < ApplicationController
  def index
  end
end

Rake spec: Tout est vert !
Test Browser: En allant à cette URL, j’obtiens une page… blanche !

Félicitations, non seulement vous avez remplis le premier test d’acceptation mais en plus, vous venez d’entrer dans la boucle du TDD ! La suite se déroulera exactement de la même façons, par une route top-down que l’on peut synthétiser en ces étapes:

  • écriture de la vue;
  • test navigateur;
  • écriture du test;
  • écriture du code.

Comme nous allons le voir par la suite, ces étapes sont répétées n fois jusqu’à ce que l’on atteigne notre objectif principal.

“Je voudrais plutôt avoir une liste d’événements venant de ma base”

Test d’acceptation: Si je vais sur la page de liste d’events, je devrais pouvoir voir des événements venant de ma base de données.

Je modifie ainsi ma vue avec ce que je souhaiterais avoir.

index.html.erb

<%- @myevents.each do |party| %>
<%= party.title %>
<% end %>

Test Browser: Gros plantage de rails, WTF is going on ?!

“Je dois régler cette erreur !”

Créons un test adapté à notre problème. Selon notre vue, nous voudrions quelquechose qui itère et présente une liste d’événements. La structure la plus adaptée est donc le tableau. Testons donc que j’ai un tableau !

event_controller_spec.rb

it 'shows an empty list when no event is available' do
  get :index
  assigns(:bouquins).should be_eql([])
end

Test Browser: J’ai maintenant une page vide ne contenant aucun évent.

“OK, mais je n’ai toujours rien, donne moi un Event !”

spec/controllers/event_controller_spec.rb

it 'shows an event when only one event available' do
  events = [OpenStruct.new]
  Event.should_receive(:all).and_return(events)
  get :index
  assigns(:myevents).should be_eql(events)
end

Le test précédent suggérait que j’appelle une méthode :all depuis mon modèle Event.
Ecrivons donc le test qui répond à la problématique dans un ficheir de test du présupposé modèle.

spec/models/event_spec.rb

describe '#all' do
  it "returns an empty array when no event" do
    Event.all.should be_eql([])
  end
end

Rake spec: D’où vient ce modèle Event ? Et cette méthode :all, dude ?!

Nous avons besoin d’un modèle Event ? Nous devons donc créer le modèle et son test associé. Passons ici par une migration: rails generate model Event title:string

Cette dernière commande nous remplira là un modèle à notre place et un fichier de migration associé

model/event.rb

class Event < ActiveRecord::Base
end

Rake spec: Vert pour mon test de modèle mais toujours rouge pour mon test de controller. ActiveRecord possède déjà une méthode :all récupérant tous les records du modèle correspondant.

Afin de corriger notre test de controller, ajoutons le code qui le fera passer au vert.

event_controller.rb

def index
  @myevents = Event.all
end

Rake spec: GREAT AND GREEN !

Créons un jeu de test directement en console

rails console

event = Event.new
event.title = “Réunion d’anciens”
event.save

event = Event.new
event.title = “Pétanque sur la place des fêtes”
event.save

Test browser: Hooray! J’ai mes deux événements qui s’affichent à l’écran. La boucle est ainsi bouclée.

Licence  CC BY-SA 4.0
Mastodon