Les tests (code)

La façon d'implémenter les tests est visibles sur le site http://guides.rubyonrails.org

Test unitaire (Modèle)

Test fonctionnel (Controleur)

Test de performance

Test d'intégration

Présentation générale

Les tests d'intégration sont une série de test automatisés visant à vérifier la non régression des différentes versions d'un logiciel. Alors que les tests unitaires visent à vérifier le bon fonctionnement d'un module ou d'une partie de code, les buts du test d'intégration sont multiples et globaux :

  • On vérifie la couverture de l'intégralité du code,
  • On vérifie que les branches assemblées ne présentent pas d'incompatibilité avec la branche principale
  • On vérifie le bon fonctionnement du code quel que soit l'ordre d'exécution des différents tests unitaires.

Le gros intéret des tests d'intégration est qu'il est de très haut niveau : il vérifie que la mécanique fonctionne bien. Exemple : j'enregistre une commande et je vérifie que la commande est bien enregistrée.

Les tests modèles valident les comportements basiques du modèle dans Ekylibre : garantit l'intégrité des données. Si on donne des données aberrantes, ça ne passe pas : on n'est pas censé valider ça. Le test d'intégration vérifie l'interface et donc l’enchaînement.

Préparation

Pour effectuer des tests, il faut d'abord effectuer des pré-requis : avoir la branche master à jour, insérer les nouvelles gems, mettre en place les données de test.

# Les données de test proviennent des fixtures : pour charger les données de fixtures : 
  rake db:fixtures:restore 
 
# (si on ne connait plus le code : rake db D ????)
 
# Dans certains cas, il faut obligatoirement compléter la base de données. On ne peut le faire que sur Master et jamais sur une branche (car on a une BD fiable sur master). 
 
# Deux personnes ne doivent pas mettre à jour les fixtures en même temps au risque d'avoir des problèmes de conflit. 
 
# La commande inverse, c'est le dump : il fait la sauvegarde et écrit dans la BDD
  rake db:fixtures:dump
 
# Avec les fichiers YML, chaque enregistrement correspond à une ligne dans la table. Les données de test sont chargées en BDD et lancées dans Ekylibre. 
 
# Pour tirer la nouvelle version de master : 
  git pull origin master
 
# Pour installer les gems qui ne seraient pas encore à jour
  bundle install
 
# Pour réinitialiser la base
  rake db:reset

Il faut aller chercher le driver pour les tests d'intégration à l'adresse suivante : https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-linux64.tar.gz

Rédaction

  • Dans un premier temps, il faut rédiger des scénarios de test qui pourront ensuite être traduits en développement. On dispose actuellement d'une douzaine de tests d'​intégration. ​
  • Dans chaque scénario, on va tester un module particulier (par exemple, saisir une vente). Dans chacun des scénarios, on va insérer des paramètres (quantité, montant hors taxes, montant TTC…) et on va également définir des valeurs attendues.
  • En prérequis, il faudra toujours vérifier que les cases ont un et un seul identifiant : pour les cases à compléter, l'​identifiant est généré automatiquement avec une série de noms et de chiffres. Il est donc plus facile d'​utiliser l'​intitulé inscrit sur le contrôle. En revanche, pour les contrôles dont on voudra vérifier les assertions, il faudra aller inspecter le code pour trouver leur identifiant unique.

Les instructions indispensables

Capybara fournit un set de commandes comprenant des fonctions et des méthodes. Pour commencer, la classe setup et le teardown peuvent être copiés collés tels quels.

class CreateAnEstimateTest < CapybaraIntegrationTest
# Initialisation des test
  setup do
    login_with_user
  end
 
# Réinitialisation des changements effectués
teardown do
    Warden.test_reset!
  end

Les commandes classiques

# Indiquer quelle page il faut aller consulter
visit ('/backend')
# Dans la première occurence de "top" (bandeau d'en-tête), click sur le bouton 'Ventes/Achat'
first ('#top').click_on('Ventes/Achat')
# Puis click sur le bouton 'Ventes' qui renvoie vers un lien
click_link ('Ventes') 
# Cantonne le sélecteur à la barre d'outil principale
within ('.main-toolbar') do
# Complète le contrôle 'Client' avec la portion de nom 'Karam' ; si un choix apparaît, sélectionne le nom 'Karamba'
fill_unroll('Client', with: 'Karam'; select, 'Karamba')
# Complète le contrôle 'PU HT' avec la valeur 100
set('PU HT', '100')
# Fonction créée comprenant deux instructions : clique sur l'élément '+ Vente standard' et fait le 'within'
add_idem ('+ Vente standard')
# Choisit une option d'une liste déroulante
select_option ('Taxe', '20% (fr)')
# Clique sur un bouton de type 'radio bouton' à l'emplacement 'Réduc'
select_radio('Type', 'Réduc')
# Permet d'effectuer une copie d'écran (qui permettront à terme de générer des démonstrateurs automatiquement)
shoot_screen('')

Les assertions

Elles servent à vérifier qu'une case donnée contient bien la valeur attendue.

Pour vérifier qu'on a ce qu'on veut dans les pages, il faut que la case ait un id et un seul. Si la case n'a pas d'id, il faut le demander.

On peut utiliser les assertions classiques :

# Création d'un outil 'content' pour identifier le contenu d'une cellule. 
 
# assert_equal : comparaison du contenu de la cellule ave le contenu attendu de 100
 
# Utilisation du to_d pour la transformation en nombre décimal du contenu de la cellule (par défaut en texte)
assert_equal 100.0, content('#twa').to_d

L'étoile ('*') servira à indiquer ce qu'il faudra développer.

Exemple

require 'test_helper'
 
class CreateAnEstimateTest < CapybaraIntegrationTest
  setup do
    login_with_user
  end
 
  teardown do
    Warden.test_reset!
  end
 
  test 'create a sale from sales' do
    visit('/backend')
    click_on('Ventes/Achats')
    click_link('Ventes')
    click_on('Classical sale')
 
    fill_unroll('Client', with: 'karam') # , select: "Gandhi Mohandas Karamchand, 196")
    check 'Format lettre'
    add_item 'Ajouter élément' do
      fill_unroll('Variante', with: 'big bag', select: 'Big bag Engrais')
      set('PU HT', '100.50')
      select_option('Taxe', '20% (fr)')
      select_radio('Type', 'Réduc')
    end
    shoot_screen 'vente-remplie.png'
    assert_equal 100.0, content('#wta').to_d
  end
  ...
end

Exécution

# Couper Firefox avant de lancer les tests d'intégration avec Selenium
  pkill firefox
 
# Ré-initialiser la base
  rake db:reset
 
# Pour créer un tenant "test" avec les données de fixtures
  rake db:fixtures:restore
 
# Pour lancer les tests d'intégration en local, utiliser la commande suivante en étant dans le répertoire ekylibre/
  rake test:integration LOCALE=fra
 
# Ajouter l'option 'DRIVER=selenium' pour voir le lancement sur le navigateur.
  rake test:integration LOCALE=fra DRIVER=selenium
 
# Pour lancer un seul test à la fois
  rake test:integration test/integration/add_an_animal_test.rb
 
# Ouvrir l'éditeur de texte via la commande suivante
# Atom peut être remplacé par n'importe quel éditeur de texte
  sudo atom /etc/hosts
 
 
# Il faut aller dans Test.ekylibre.lan
 
# Remplacer la première ligne "127.0.0.1	localhost" par "127.0.0.1	localhost test.ekylibre.lan" dans le fichier /etc/hosts et sauvegarder
 
# Lancer le serveur local dans un terminal avec l'instruction suivante
 TENANT=test foreman s ou encore rails s
 
# Jouer avec Ekylibre en allant sur http://test.ekylibre.lan:8080 (n° du port utilisé par Foreman, 3000 pour rails) avec Firefox ou Chrome
 
# Ecrire la base de données dans les fichiers test/fixtures/ , par exemple, lorsque je veux modifier le nom d'un contrôle pour correspondre aux noms définis dans les tests.
  rake db:fixtures:dump
 
# Pour voir les changements
  git diff
 
# Pour revenir à l'état d'origine 
  git checkout
 
# Pour annuler les changements enregistrés dans les données fixtures (restaure les fichiers)
  git checkout -f --test/fixtures/
 

Pour afficher les messages d'erreur, il ré-éxécute les tests pour donner des détails.

Test modèle : CI concerne les tests d'intégration faits par Travis. Controllers, exchangers, helpers, models fixtures-files contient tous les test pour exchangers Lib : bibliothèque de fonctions support.

Les tests modèles valident les comportements basiques du modèle dans Ekylibre : garantit l'intégrité des données. Si on donne des données aberrantes, ça ne passe pas : on n'est pas censé valider ça. Le test d'intégration vérifie l'interface et donc l’enchaînement.

Dans le modèle, on a d'abord les relations puis les validations Il faut vérifier la couverture de code

  • github/ekylibre/ekylibre/coverage
  • codacy/app/ekylibre/ekylibre