[RUBY] À propos de la structure de répertoires de RSpec et du rôle de chaque spécification

introduction

Concernant le framework de test de l'application Web en cours de création, nous migrons de Minitest vers RSpec en tenant compte du Dernier article créé. À ce moment-là, j'ai senti qu'il était nécessaire de connaître les types de tests dont Minitest n'était pas très conscient. La façon d'écrire un test varie selon que le test est un test d'interface utilisateur, un test de contrôleur ou un test de modèle. Cet article résume brièvement la structure du répertoire RSpec et comment écrire du code pour chaque type de test. J'y ai fait référence → Introduction à RSpec utilisable, Partie 1 «Comprendre la syntaxe de base et les fonctions utiles de RSpec» Everyday Rails-Introduction to Rails Testing with RSpec

Répertoires principaux de RSpec

Le type de test RSpec est appelé Spec. Les spécifications sont généralement placées dans une structure de répertoire légitime qui décrit leur objectif.

** [Structure du répertoire RSpec principal] **

spec --- modèles      | | ー demandes      | | ー caractéristiques      | | ー aides      | | ー expéditeurs      | | ー système

À propos du rôle principal de Spec

Ici, nous allons présenter les rôles de ** Model Spec **, ** Request Spec **, ** Feature Spec ** et ** System Spec **.

Model Spec Model Spec teste les modèles Rails tels que la validation. Vérifiez avec l'exemple de code ci-dessous.

spec/models/user_spec.rb


RSpec.describe User, type: :model do

  describe 'Nom d'utilisateur' do
    it 'Si vide, il est dans un état invalide' do
      user = User.new( name: '  ',
                       email: '[email protected]',
                       password: 'password',
                       password_confirmation: 'password')
      expect(user).to_not be_valid
    end

    it 'S'il est trop long, il est dans un état invalide' do
      user = User.new( name: 'a' * 51,
                       email: '[email protected]',
                       password: 'password',
                       password_confirmation: 'password')
      expect(user).to_not be_valid
    end
  end
end

Je vérifierai le contenu un par un.

-Spécifiez les spécifications avec `` type :: model ''. Nous testons ici le modèle utilisateur.

· `` Décrire '' regroupe les résultats attendus. Il déclare "tester le modèle utilisateur" et "tester le nom d'utilisateur".

-`ʻUser.new`` crée un utilisateur.

-`ʻitest groupé en unités plus petites que décrire`` appelé ** exemple **. Vous pouvez avoir plusieurs attentes dans «it». Cependant, si vous faites une erreur au milieu, le futur ne coulera pas, donc fondamentalement une attente est recommandée pour chaque «it».

ʻExpect`` décrit l'attente (attente). ʻExpect (user) .to_not be_validteste que" l'utilisateur n'est pas valide? " L'un des avantages de RSpec est que vous pouvez écrire des tests comme en anglais. La partie to_not be_valid`` s'appelle ** matcher ** et il en existe différents types. D'autres correspondants peuvent être trouvés à ici.

Request Spec Selon les Documents officiels, Request Spec est «via la pile complète, y compris le routage». , Il est conçu pour piloter l'opération sans le stub [^ 1]. " Le fait est qu'il s'agit d'un test côté serveur. Request Spec vous permet d'utiliser des méthodes HTTP (obtenir, publier, supprimer, etc.) lors du test de la réponse du contrôleur.

spec/requests/access_to_users_spec.rb


RSpec.describe "AccessToUsers", type: :request do 

  describe 'Restrictions d'accès pour les utilisateurs qui ne sont pas connectés' do
    it 'Supprimer l'utilisateur' do
      user = User.create( name: 'kojiro',
                          email: '[email protected]',
                          password: 'password',
                          password_confirmation: 'password')
      expect {
              delete user_path(user)
              }.to change(User, :count).by(0)
    end
  end
end

Ici, nous utilisons la méthode supprimer '' pour tester qu'un utilisateur qui n'est pas connecté ne reflète pas la suppression de l'utilisateur. ```Attendre {delete user_path (user)} .to change (User ,: count) .by (0) signifie que lors de l'accès à delete user_path (user), la différence dans le nombre d'utilisateurs avant et après l'accès est de 0. Prédire. "

Feature Spec Feature Spec est un test d'interface utilisateur. Official Document recommande d'utiliser System Spec, qui a des fonctions similaires de RSpec 3.7. Faire.

System Spec La spécification système, comme la spécification de fonctionnalité, est principalement un test d'interface utilisateur. Vous pouvez écrire un test E2E (de bout en bout) à exécuter sur votre navigateur. Ceci est un test frontal. De plus, par défaut, nous exécutons des tests à l'aide du navigateur Chrome. Utilisez ** Capybara ** pour simuler l'activité du navigateur. Nous allons vérifier de quel type de description il s'agit avec l'exemple de code ci-dessous.

spec/systems/user_logins_spec.rb


RSpec.describe "UsersLogins", type: :system do
  it 'Connexion valide' do
    user = User.create( name: 'kojiro',
                        email: '[email protected]',
                        password: 'password',
                        password_confirmation: 'password')
    visit login_path
    fill_in 'adresse mail', with: '[email protected]'
    fill_in 'mot de passe', with: 'password'
    click_button 'S'identifier'
    expect(current_path).to eq user_path(user)
  end
end

Je vérifierai le contenu un par un.

-D'abord, créez un utilisateur avec `ʻUser.create`` et enregistrez-le.

-Les méthodes telles que visit '', fill_in '' et `` click_button '' sont des langages spécifiques au domaine de Capybara appelés DSL.

  1. visite '' représente une visite de la page. Utilisez visit login_path '' pour accéder à la page de connexion.
  2. fill_in '' représente la saisie de caractères dans la zone de texte. Dans fill_in'email address '', avec: 'user @ example.com'``, vous avez entré'[email protected]' dans la zone de texte intitulée'email address '.
  3. click_button Représente un clic sur un bouton.

D'autres DSL peuvent être trouvés à ici.

-`ʻExpect (current_path) .to eq user_path (user) `` teste "si le chemin actuel est le même que user_path (utilisateur) (détails de l'utilisateur)".

En outre, lorsque le test échoue, la spécification système affiche une capture d'écran de la pièce défaillante avec un message d'erreur du contenu défaillant. Comme test, changez le ```user_path (user) de l'attente en login_path`` et lancez le test. Ensuite, la sortie suivante a été sortie.

Failures:

  1)UsersLogins Connexion valide, déconnexion
     Failure/Error: expect(current_path).to eq login_path
     
       expected: "/login"
            got: "/users/1"
     
       (compared using ==)
     
     [Screenshot]: /(Chemin du programme)/myapp/tmp/screenshots/failures_r_spec_example_groups_users_logins_Connexion valide, déconnexion_119.png

     
     # ./spec/system/users_login_spec.rb:14:in `block (2 levels) in <top (required)>'

failures_r_spec_example_groups_users_logins_有効なログイン、ログアウト_119.png

Comme vous pouvez le voir sur la capture d'écran, vous voyez ʻuser_path (user) (écran des détails de l'utilisateur) au lieu du résultat attendu `login_path`` (écran de connexion).

Résumé

À propos, dans Request Spec, Capybara ne peut pas être utilisé, et dans Feature Spec, la méthode HTTP ne peut pas être utilisée. Il sera nécessaire de déterminer si le test que vous essayez d'implémenter est du côté serveur ou du côté frontal.

[^ 1]: Un stub est un substitut à un sous-module qu'un module appelle lors du test d'un module dans un programme informatique. ([wiki](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%BF%E3%83%96#:~:text=%E3%82%B9%E3% 82% BF% E3% 83% 96% EF% BC% 88stub% EF% BC% 89% E3% 81% A8% E3% 81% AF% E3% 80% 81,% E7% 94% A8% E3% 81 % 84% E3% 82% 8B% E4% BB% A3% E7% 94% A8% E5% 93% 81% E3% 81% AE% E3% 81% 93% E3% 81% A8% E3% 80% 82 & texte =% E9% 80% 86% E3% 81% AB% E4% B8% 8A% E4% BD% 8D% E3% 83% A2% E3% 82% B8% E3% 83% A5% E3% 83% BC% E3% 83% AB% E3% 81% AE,% E3% 82% A6% E3% 82% A7% E3% 82% A2% E3% 81% AE% E5% A0% B4% E5% 90% 88% E À partir de% BC% 89% E3% 81% A8% E5% 91% BC% E3% 81% B6% E3% 80% 82)) Ici, Rails fonctionne dans le test sans utiliser de substitut pour son module inférieur. Est capable de conduire.

Recommended Posts

À propos de la structure de répertoires de RSpec et du rôle de chaque spécification
À propos de l'instruction et de l'instruction if
[Pour les débutants] À propos des expressions lambda et de l'API Stream