Article écrit par Willow Barraco
Récemment j’ai travaillé sur un nouveau projet qui a déjà toute une batterie de tests présente et je me suis heurtée à une problématique :
Comment ajouter de nouveaux tests, avec de nouvelles fixtures, sans risquer de casser les tests existants ?
Typiquement lorsque j’ai voulu ajouter des fixtures pour mes nouveaux tests, les anciens ne passaient plus, car ils n’ont pas été assez bien pensés initialement. Au lieu d’investir davantage de temps à réécrire ces tests existants j’aimerais rendre indépendant mes nouveaux tests des anciennes données.
Pour m’affranchir de cette contrainte et pouvoir ajouter de nouveaux tests en toute sérénité, j’ai eu envie d’utiliser un genre de contexte. D’écrire mes tests et fixtures dans un nouveau dossier bien séparé de l’existant. L’idée semble simple en apparence, mais en vérité, j’ai passé plusieurs jours à me casser la tête dessus. Les fixtures au sein d’une application Rails sont faites pour fonctionner facilement sans configuration mais dès qu’on essaie d’être originaux on est vite bloqués.
Voici donc, humblement, la solution que j’ai adoptée. Il existe probablement d’autres façons de faire, mieux ou pire. Moi j’ai trouvé ça !
J’ai développé de nouvelles fonctionnalités autour d’un projet client que l’on nommera ici Address Book. J’ai aussi en tête que j’aurai sans doute besoin d’ajouter de nouveaux contextes de tests à l’avenir. J’ai donc créé le dossier test/contexts/address_book/
, racine de mon contexte :
# test/contexts/address_book/address_book_test_helper.rb require_relative '../../../config/environment' require 'rails/test_help' class ActiveSupport::AddressBookIntegrationTest < ActionDispatch::IntegrationTest self.fixture_path = "#{Rails.root}/test/contexts/address_book/fixtures/" self.use_transactional_tests = false fixtures :all end
Grace à fixture_path
, les fixtures se trouvant dans le dossier fixtures/
du dossier de mon contexte seront utilisées.
J’ai également dû désactiver use_transactional_tests
car la commande utilisée pour lancer les tests est $ rake db:drop; rake db:create && rake db:structure:load && rake db:fixtures:load && rake test ALL=yes BACKTRACE=yes
. Les fixtures sont donc chargées avant les tests et chaque test va déclencher un rollback de la base de données. Or mes tests utilisent un contexte différent donc si je ne désactive pas cela mes nouvelles fixtures seront rollback.
Je peux maintenant utiliser ce AddressBookIntegrationTest
comme base pour mes tests d’intégration :
# test/contexts/address_book/fixtures/contacts.yml jeremy: address_1: "Rue de la ré" address_2: "Au rez de chaussé" zip_code: "69001" city: "Lyon" country: "France" phone: "+33423434565", mobile_phone: "+33623434565", email: "jeremy@yopmail.com"
# test/contexts/address_book/contact_test_helper.rb require_relative "address_book_test_helper" class ContactTest < ActiveSupport::AddressBookIntegrationTest test "using a basic contact" do get( "/api/v2/contacts/#{contacts(:jeremy).email}", ) expected = { "id" => contacts(:jeremy).id, "address_1" => "Rue de la ré", "address_2" => "Au rez de chaussé", "zip_code" => "69001", "city" => "Lyon", "country" => "France", "phone" => "+33423434565", "mobile_phone" => "+33623434565", "email" => "jeremy@yopmail.com" } assert_response :success assert_equal expected, JSON.parse(@response.body) end test "using an unknown email" do get( "/api/v2/contacts/toot@tiit.com", ) assert_response 404 end end
Voilà voilà. Des bisous à la moi du futur !