[RUBY] [3e] Les débutants de RSpec ont écrit SystemSpec en tant que débutant (édition finale)

introduction

Ceci est l'article précédent [[2nd] RSpec débutant a écrit SystemSpec en tant que débutant (édition swamp)](https://qiita.com/komaitaira/items/b9efc86cde48fb5ca8ef "[2nd] RSpec beginner Cependant, c'est une continuation de "J'ai essayé d'écrire SystemSpec en tant que débutant (édition marécageuse)"), et c'est l'édition finale de SystemSpec (spécification système).

Si vous voulez en savoir plus sur ModelSpec, veuillez consulter ici. ..

De plus, l'autre jour, une session d'étude pour débutants (RSpec Beginners !!) a eu lieu avec la gentillesse du RSpec male Junichi Ito @jnchito. J'ai également participé à "RSpec Beginners !!"), donc je pense que vous pouvez approfondir votre compréhension en regardant cette vidéo, alors jetez un œil si vous le souhaitez.

Que faire dans cet article

Non couvert dans cet article

supposition

Test articles_spec.rb

① Utilisez FactoryBot et préparez les données d'article à l'avance

Préparez les données préliminaires à l'aide du FactoryBot familier. Il a été créé au moment de la partie 1, mais il sera également utilisé lors de la rédaction des spécifications du système, il est donc répertorié ci-dessous pour référence. Pour plus de détails sur FactoryBot, reportez-vous à l'article sur les spécifications du modèle.

①spec/factories/articles.rb


FactoryBot.define do
  #Utilisez FactoryBot et préparez les données d'article à l'avance
  FactoryBot.define do
  factory :article do
    title { "Titre du test" }
    body { "Corps de test" }
    is_active { true }
    company
    genre
  end
end

② Description du code spécifique

Maintenant écrivons le code de test. Lancer $ rails g rspec: les articles système créeront articles_spec.rb dans le dossier spec / system. Le code de test (mouvement réel sur le navigateur, etc.) sera écrit dans ce fichier. Voici un exemple complet.

②spec/system/articles_spec.rb


require 'rails_helper'

RSpec.describe "Articles", type: :system do
  describe 'Test d'article' do
    let(:company){FactoryBot.create(:company)}
    let(:genre){FactoryBot.create(:genre)}
    let!(:article){FactoryBot.create(:article, company: company, genre: genre)}
    before do
      visit new_company_session_path
      fill_in 'adresse mail', with: company.email
      fill_in 'mot de passe', with: company.password
      click_button 'S'identifier'
    end
    describe 'Test de la barre latérale' do
      context 'Vérifiez l'affichage' do
        it 'La recherche d'article est affichée' do
          expect(page).to have_content "Recherche d'articles"
          expect(current_path).to eq corporate_articles_path
        end
        it 'L'enregistrement de l'article est affiché' do
          expect(page).to have_content "Enregistrement d'article"
          expect(current_path).to eq corporate_articles_path
        end
      end
    end

    describe 'Post test' do
      context 'Transition vers une nouvelle page de publication d'article' do
        it 'Transition' do
          click_on 'Enregistrer un article'
          expect(page).to have_content "Publier un nouvel article"
          expect(current_path).to eq new_corporate_article_path
        end
      end
      context 'Vérifiez l'affichage' do
        before do
          visit new_corporate_article_path
        end
        it 'Le formulaire d'image du haut de l'article s'affiche' do
          expect(page).to have_field 'article[image]'
        end
        it 'La boîte de sélection du genre s'affiche' do
          expect(page).to have_select 'Genre'
        end
        it 'La boîte de sélection de l'état de la liste s'affiche' do
          expect(page).to have_select 'Statut de publication'
        end
        it 'Le formulaire du titre de l'article s'affiche' do
          expect(page).to have_field 'Le titre de l'article'
        end
        it 'Le formulaire de contenu de l'article s'affiche' do
          expect(page).to have_field 'Contenu de l'article'
        end
        it 'Le bouton de publication d'article s'affiche' do
          expect(page).to have_button 'Publier un article'
        end
      end
      context 'Publier un article' do
        before do
          visit new_corporate_article_path
        end
        it 'Publication réussie' do
          select "Genre de test", from: 'Genre'
          select "Maintenant publié", from: 'Statut de publication'
          fill_in 'Le titre de l'article', with: "RSpec est difficile"
          fill_in 'Contenu de l'article', with: "C ’est difficile, mais je suis content si la suite de tests passe et que tout devient vert."
          click_button "Publier un article"
          expect(page).to have_content "J'ai posté un nouvel article."
        end
        it 'La publication échoue' do
          fill_in 'Le titre de l'article', with: ""
          click_button "Publier un article"
          expect(page).to have_content "L'article n'a pas été enregistré en raison de l'erreur."
        end
      end
    end
  
    describe 'Test d'édition' do
      context 'Confirmation de la transition vers chaque écran' do
        it 'Vous pouvez passer à l'écran des détails de l'article' do
          click_on article.title
          expect(page).to have_content "Détails de l'article"
          expect(current_path).to eq corporate_article_path(article)
        end
        it 'Vous pouvez passer à l'écran de modification d'article' do
          visit corporate_article_path(article) #Transition vers l'écran des détails de l'article
          click_on "Éditer"
          expect(page).to have_content "Modification des informations sur l'article"
          expect(current_path).to eq edit_corporate_article_path(article)
        end
      end
      context 'Confirmation de l'affichage et de l'édition' do
        before do
          visit edit_corporate_article_path(article)
        end
        it 'Le formulaire d'image du haut de l'article s'affiche' do
          expect(page).to have_field 'article[image]'
        end
        it 'La boîte de sélection du genre s'affiche' do
          expect(page).to have_select('Genre', selected: 'テストGenre')
        end
        it 'La boîte de sélection de l'état de la liste s'affiche' do
          expect(page).to have_select('Statut de publication', selected: 'Maintenant publié')
        end
        it 'Le formulaire du titre de l'article s'affiche' do
          expect(page).to have_field 'Le titre de l'article', with: article.title
        end
        it 'Le formulaire de contenu de l'article s'affiche' do
          expect(page).to have_field 'Contenu de l'article', with: article.body
        end
        it 'Le bouton d'édition d'article s'affiche' do
          expect(page).to have_button 'Enregistrez vos modifications'
        end
        it 'Modification réussie' do
          select "Publication suspendue"
          fill_in 'Le titre de l'article', with: "J'arrêterai de publier jusqu'à ce que je puisse écrire RSpec en douceur"
          click_button 'Enregistrez vos modifications'
          expect(page).to have_content 'La mise à jour des informations sur l'article est terminée.'
          expect(page).to have_content '[État actuel de la publication: publication suspendue]'
          expect(current_path).to eq corporate_article_path(article)
        end
        it 'La modification échoue' do
          fill_in 'Le titre de l'article', with: ""
          click_button 'Enregistrez vos modifications'
          expect(page).to have_content "L'article n'a pas été enregistré en raison de l'erreur."
        end
      end
    end
  end
end


Comme je l'ai expliqué dans les spécifications du modèle, en publiant l'article ⑴ Il y a une entreprise, ⑵ Il y a un genre d'articles, ⑶ Des articles peuvent être publiés C'est devenu un flux. Par conséquent, vous pouvez comprendre qu'une entreprise existe et qu'il est nécessaire de sélectionner un genre à l'avance pour publier un article. Notez que la différence avec la dernière fois est que les données créées par FactoryBot sont enregistrées à l'aide de let, et non de la variable d'instance.


Parlons maintenant des tests d'articles. Voir l'exemple de code terminé pour un test d'affichage. Peut-être que vous qui avez lu jusqu'à cette 3ème fois, vous comprendrez sans expliquer. Veuillez noter qu'il existe plusieurs types uniquement pour have_ ◯◯. Consultez l'exemple de code ci-dessous.

②spec/system/articles_spec.rb


      context 'Publier un article' do
        before do
          visit new_corporate_article_path
        end
        it 'Publication réussie' do
          select "Genre de test", from: 'Genre' # セレクトボックスからGenreを選択
          select "Maintenant publié", from: 'Statut de publication' # セレクトボックスからStatut de publication(Maintenant publié or 掲載停止中)choisir
          fill_in 'Le titre de l'article', with: "RSpec est difficile" #entrer le titre
          fill_in 'Contenu de l'article', with: "C ’est difficile, mais je suis content si la suite de tests passe et que tout devient vert." # Contenu de l'articleを入力
          click_button "Publier un article" # Publier un articleボタンを押下
          expect(page).to have_content "J'ai posté un nouvel article." 
        end
        it 'La publication échoue' do
          fill_in 'Le titre de l'article', with: ""
          click_button "Publier un article"
          expect(page).to have_content "L'article n'a pas été enregistré en raison de l'erreur."
        end
      end

Dans l'exemple de code ci-dessus, nous passons d'abord à la page où le formulaire de publication est affiché dans le bloc avant. Ensuite, publiez le formulaire 1. Sélectionnez le genre, 2. Sélectionnez le statut de publication, 3. Entrez le titre, 4. Entrez le contenu de l'article et appuyez sur le bouton Publier.

** Point de trébuchement: étreindre: "Sélectionnez la case de sélection" ** Dans la sélection de la boîte de sélection ci-dessus, il est décrit comme "sélectionner" genre de test ", à partir de:" genre ". Ce n'est peut-être pas une pierre d'achoppement si vous le faites normalement, mais j'ai eu beaucoup de problèmes ici aussi, alors je vais le partager. La cause du trébuchement était que la ** balise d'étiquette n'était pas écrite correctement **, et je ne pouvais pas bien sélectionner la case de sélection. Voici comment écrire ma mauvaise étiquette d'étiquette.

Ruby:corporate/articles/new.html.erb


<%= f.label :Genre%><br>
<%= f.collection_select :genre_id, Genre.all, :id, :genre_name, include_blank: "--Veuillez sélectionner--" %>

La description de «<% = f.label: Genre%>» est incorrecte. Il s'affiche sur le navigateur sans aucun problème, mais lorsque je le vérifie avec l'outil de vérification Pour une raison quelconque, l'attribut for est un mélange d'anglais et de japonais (for = "article_genre"), comme <label for =" article_genre "> genre </ label>. Je n'arrive pas à faire un bon choix.
Voici comment écrire la balise d'étiquette correcte.

Ruby:corporate/articles/new.html.erb


<%= f.label :genre_id, "Genre" %><br>
<%= f.collection_select :genre_id, Genre.all, :id, :genre_name, include_blank: "--Veuillez sélectionner--" %>

** Ajouté le 2 octobre 2020 ** Concernant la façon d'écrire la balise label ci-dessus, il semble préférable de mettre la version traduite dans un fichier YAML et de l'afficher dans la vue au lieu de l'écrire solidement dans la vue sous la forme de "genre". Je vais le décrire de cette manière une fois, mais je le corrigerai plus tard.

L'affichage lorsqu'il est visualisé avec l'outil de vérification est comme <label for =" article_genre_id "> genre </ label>.

Plutôt que de décrire le test, cela peut être une partie simple car la vue a été mal écrite en premier lieu, mais quand j'ai reçu des conseils dans les commentaires du deuxième article, j'ai finalement compris la cause.

Il n'y a peut-être pas beaucoup de gens qui éprouvent des difficultés avec cela, mais pour le moment, cet article [HTML] Pourquoi devriez-vous ajouter l'attribut for à la balise lavel? Explication approfondie de la façon d'utiliser! Explique en détail la balise label.

Probablement, si ** for attribute contient une valeur correcte (genre_id dans ce cas), il sera lié par programmation à l'élément d'entrée **. J'ai beaucoup appris. Si, pour une raison quelconque, le test ne passe pas comme moi, vous pouvez le vérifier avec l'outil de vérification de Chrome!

Le test qui échoue au reste des articles et le test d'édition de l'article sont fondamentalement les mêmes qu'avant, alors veuillez l'écrire en référence au code terminé!

Test rooms_spec.rb

① Description du code spécifique

Le test est enfin terminé! Ce test DM / notification met fin au test des fonctions principales. faisons de notre mieux! À propos, FactoryBot n'est pas utilisé dans ce test. Voici un exemple du code complété.

①spec/system/rooms_spec.rb


require 'rails_helper'

RSpec.describe "Rooms", type: :system do
  let(:user){FactoryBot.create(:user)}
  let!(:company){FactoryBot.create(:company)}

  describe 'Test DM' do
    before do
      visit new_user_session_path
      fill_in 'adresse mail', with: user.email
      fill_in 'mot de passe', with: user.password
      click_button 'S'identifier'
      expect(page).to have_content 'Vous êtes maintenant connecté.'
    end

    context 'Vérifiez l'affichage' do
      it 'Vous pouvez passer à la liste d'experts' do
        click_on 'Expert'
        expect(current_path).to eq companies_path
      end
      it 'Un bouton pour passer à l'écran des détails de l'entreprise et démarrer le DM s'affiche' do
        visit companies_path
        click_on 'Test Co., Ltd.'
        expect(current_path).to eq company_path(company)
        expect(page).to have_content 'Test Co., Ltd.'
        expect(page).to have_button 'Démarrer DM'
      end
    end

    context 'Côté individuel: envoi d'un message' do
      before do
        visit company_path(company) #Passer à l'écran des détails de l'entreprise
        click_on 'Démarrer DM'
      end
      it 'Vous pouvez entrer dans la salle de discussion et le formulaire de soumission sera affiché' do
        expect expect(page).to have_field 'Veuillez saisir un message'
      end
      it 'Peut envoyer des messages' do
        fill_in 'Veuillez saisir un message', with: 'Message d'essai'
        click_button 'Envoyer'
        expect(page).to have_content 'Message d'essai'
      end
      it 'Après l'envoi d'un message, l'historique d'envoi est ajouté à l'écran de la liste DM' do
        fill_in 'Veuillez saisir un message', with: 'Message d'essai'
        click_button 'Envoyer'
        expect(page).to have_content 'Message d'essai' #Messages dans la salle de chat
        visit rooms_path
        expect(page).to have_content 'Message d'essai' #Message d'écran de la liste DM
        expect(page).to have_link 'Voir message'
      end
    end

    context 'Côté entreprise: réception-envoi de message(réponse)' do
      before do
        #Envoyez un message du côté individuel
        visit company_path(company)
        click_on 'Démarrer DM'
        fill_in 'Veuillez saisir un message', with: 'Message d'essai'
        click_button 'Envoyer'
        logout(user)
        #Connexion entreprise
        visit new_company_session_path
        fill_in 'adresse mail', with: company.email
        fill_in 'mot de passe', with: company.password
        click_button 'S'identifier'
        expect(page).to have_content 'Vous êtes maintenant connecté.'
      end

      it 'Le nombre de notifications est affiché dans l'en-tête' do
        expect(page).to have_content '1 Notification'
      end
      it 'Vous pouvez accéder à l'écran de la liste des notifications à partir du lien, et vous pouvez vérifier la réception des messages d'utilisateurs individuels.' do
        click_on 'notification'
        expect(page).to have_content 'notification'
        expect(page).to have_content 'Il y a un message de Test Taro'
      end
      it 'Vous pouvez entrer dans la salle de discussion à partir du lien et le message reçu sera affiché' do
        click_on 'notification'
        click_on 'message'
        expect expect(page).to have_content 'Message d'essai'
      end
      it 'Peut envoyer des messages' do
        click_on 'notification'
        click_on 'message'
        fill_in 'Veuillez saisir un message', with: 'Répondre au message de test'
        click_button 'Envoyer'
        expect(page).to have_content 'Répondre au message de test'
      end
    end
  end
end

Dans le test DM / notification, je voudrais expliquer séparément pour le côté individuel et le côté entreprise. Le premier est le ** test individuel **. Consultez l'exemple de code ci-dessous.

[Côté individuel] Test DM / notification

①spec/system/rooms_spec.rb


    context 'Côté individuel: envoi d'un message' do
      before do
        visit company_path(company) #Passer à l'écran des détails de l'entreprise
        click_on 'Démarrer DM'
      end
      it 'Vous pouvez entrer dans la salle de discussion et le formulaire de soumission sera affiché' do
        expect expect(page).to have_field 'Veuillez saisir un message'
      end
      it 'Peut envoyer des messages' do
        fill_in 'Veuillez saisir un message', with: 'Message d'essai'
        click_button 'Envoyer'
        expect(page).to have_content 'Message d'essai'
      end
      it 'Après l'envoi d'un message, l'historique d'envoi est ajouté à l'écran de la liste DM' do
        fill_in 'Veuillez saisir un message', with: 'Message d'essai'
        click_button 'Envoyer'
        expect(page).to have_content 'Message d'essai' #Messages dans la salle de chat
        visit rooms_path
        expect(page).to have_content 'Message d'essai' #Message d'écran de la liste DM
        expect(page).to have_link 'Voir message'
      end
    end

Je pense qu'il y a des points particulièrement difficiles.

** Dans le test'Peut envoyer un message '**

  1. fill_in'Enter message ', avec:' Test message' ⇨ Saisir le message de test string dans la zone de texte
  2. click_button'Send'⇨ Appuyez sur le bouton d'envoi
  3. ʻattend (page) .to have_content'test message'`⇨ Confirmer que le message a été envoyé en attendant la chaîne "test message" sur la même page

C'est devenu un flux. チャットルーム内メッセージ

** Dans le test "Après l'envoi d'un message, l'historique de transmission est ajouté à l'écran de la liste DM" **

  1. ** 1st ** ʻattendez (page) .to have_content'test message'`⇨ Vérifiez le message envoyé dans la salle de chat
  2. visit rooms_path ⇨ Passer à l'écran de la liste DM
  3. ** 2nd ** ʻattendez (page) .to have_content'Test message'`⇨ Confirmez que le dernier message est affiché sur l'écran de la liste DM

C'est devenu un flux. DM一覧画面メッセージ

Ce qui précède est le test DM du côté individuel. Ensuite, je voudrais expliquer le test du côté de l'entreprise. Consultez l'exemple de code ci-dessous.

[Côté entreprise] Test DM / notification

①spec/system/rooms_spec.rb


    context 'Côté entreprise: réception-envoi de message(réponse)' do
      before do
        #Envoyez un message du côté individuel
        visit company_path(company)
        click_on 'Démarrer DM'
        fill_in 'Veuillez saisir un message', with: 'Message d'essai'
        click_button 'Envoyer'
        logout(user)
        #Connexion entreprise
        visit new_company_session_path
        fill_in 'adresse mail', with: company.email
        fill_in 'mot de passe', with: company.password
        click_button 'S'identifier'
        expect(page).to have_content 'Vous êtes maintenant connecté.'
      end

      it 'Le nombre de notifications est affiché dans l'en-tête' do
        expect(page).to have_content '1 Notification'
      end
      it 'Vous pouvez accéder à l'écran de la liste des notifications à partir du lien, et vous pouvez vérifier la réception des messages d'utilisateurs individuels.' do
        click_on 'notification'
        expect(page).to have_content 'notification'
        expect(page).to have_content 'Il y a un message de Test Taro'
      end
      it 'Vous pouvez entrer dans la salle de discussion à partir du lien et le message reçu sera affiché' do
        click_on 'notification'
        click_on 'message'
        expect expect(page).to have_content 'Message d'essai'
      end
      it 'Peut envoyer des messages' do
        click_on 'notification'
        click_on 'message'
        fill_in 'Veuillez saisir un message', with: 'Répondre au message de test'
        click_button 'Envoyer'
        expect(page).to have_content 'Répondre au message de test'
      end
    end

Ce n'est pas non plus particulièrement difficile. Tout d'abord, dans le bloc avant, décrivez jusqu'au point où le côté individuel a envoyé un message, puis la société s'est connectée. ** 'Le nombre de notifications est affiché dans l'en-tête' ** Dans le test ʻAttendez (page) .to have_content '1 Notification'`⇨ Lorsque vous vous connectez, vérifiez que l'en-tête affiche le nombre de notifications en fonction du nombre de messages et un lien vers la liste des notifications.

DM一覧画面メッセージ

** 'Vous pouvez passer à l'écran de la liste des notifications à partir du lien et confirmer la réception des messages d'utilisateurs individuels' ** Dans le test ʻAttendez-vous (page) .to have_content'Il y a un message de Test Taro'` ⇨ Lorsque vous passez à l'écran de la liste des notifications, vous pouvez vérifier de qui provient le message.

DM一覧画面メッセージ

Tout ce que vous avez à faire est d'entrer dans la salle de discussion, de vérifier si un message arrive et de voir si vous pouvez également envoyer (répondre) un message à partir d'ici.

DM一覧画面メッセージ

Ceci est le test DM / notification.

À la fin

Cette fois, nous avons résumé les tests de publication, d'édition, de DM et de notification des articles en fonction des spécifications du système. Ceci complète les spécifications système que j'ai écrites en deux parties! Je l'ai écrit comme une critique de moi-même, mais j'ai pensé à nouveau qu'il y avait encore des améliorations. Je voudrais faire de petites corrections pour que les débutants qui voient cela ne disent pas "Qu'est-ce que c'est, je ne comprends pas!".

Au début, j'ai eu beaucoup de problèmes avec des choses que je ne comprenais pas, mais même ainsi, la session d'étude pour les débutants l'autre jour RSpec Beginners !! J'ai pu écrire des tests moi-même plus que lorsque j'y ai participé, et si on me demande quelque chose, je pourrai le dire un peu aux gens.

Nous remercions M. Ito (@jnchito) d'avoir offert une telle opportunité et toutes les personnes qui nous ont invités.

Aussi, bien qu'il soit enfantin, j'espère que cet article sera utile aux débutants de RSpec. Merci d'avoir regardé jusqu'au bout!

Article de référence

[Introduction à RSpec qui peut être utilisé, Partie 4 "Toute opération de navigateur est gratuite! Encyclopédie Capybara inversée"](https://qiita.com/jnchito/items/607f956263c38a5fec24 "Introduction à RSpec qui peut être utilisé, Partie 4" Toute opération de navigateur est gratuite ! Encyclopédie Capybara inversée "") [HTML] Pourquoi l’attribut for devrait-il être ajouté à la balise lavel? Explication approfondie de la façon d'utiliser!

Recommended Posts

[3e] Les débutants de RSpec ont écrit SystemSpec en tant que débutant (édition finale)
[2e] RSpec débutant a écrit SystemSpec en tant que débutant (édition Numa)
[1er] RSpec débutant a essayé d'écrire ModelSpec en tant que débutant