This is the previous article [[2nd] RSpec beginner wrote SystemSpec as a beginner (swamp edition)](https://qiita.com/komaitaira/items/b9efc86cde48fb5ca8ef "[2nd] RSpec beginner However, it is a continuation of "I tried to write SystemSpec as a beginner (swamp edition)"), and it is the final edition of SystemSpec (system spec).
If you want to know about ModelSpec, please see here. ..
Also, the other day, a study session for beginners (RSpec Beginners !!) was held with the kindness of RSpec male Junichi Ito @jnchito. I also participated in "RSpec Beginners !!"), so I think that you can deepen your understanding by watching this video, so please have a look if you like.
** Target **
I'm trying to write RSpec, but I don't know what it is. A beginner who says: hugging :.
However, Mr. Ito's [Introduction to RSpec that can be used, Part 1 "Understanding the basic syntax and useful functions of RSpec"](https://qiita.com/jnchito/items/42193d066bd61c740612 "Introduction to RSpec that can be used, Part 1" Understand the basic syntax and useful features of RSpec "")
It is desirable to understand the role of describe, it, expect at least, such as looking at the contents of this article to some extent or having done something.
** Reference code ** As mentioned above, I will describe it with reference to my portfolio, so I will put a GitHub link here, but the test target is the site Please note that we are focusing on core functions. ** [Core functions of the site] ** (New registration / login / editing of individual / corporate members, application for corporate member registration, posting / editing of articles, DM, notification, etc.)
** Preparation for writing tests ** In order to write a test with RSpec, you need to put in and configure some gems, including gem'rspec-rails'. Please prepare to write the test first and then read it. What you need is described in "Everyday Rails-Introduction to Rails Testing with RSpec". Or rather, if you look at this, you can understand it without looking at this article. If you want to see the code as a concrete example, please read it as it is. (It's really just for reference)
Prepare pre-data using the familiar Factory Bot. It was created at the time of Part 1, but it will also be used when writing system specifications, so it is listed below for reference. For more information on FactoryBot, please refer to the model specs article.
①spec/factories/articles.rb
FactoryBot.define do
#Use FactoryBot and prepare article data in advance
FactoryBot.define do
factory :article do
title { "Test title" }
body { "Test body" }
is_active { true }
company
genre
end
end
Now let's write the test code. Running $ rails g rspec: system articles will create articles_spec.rb in the spec / system folder. The test code (actual movement on the browser, etc.) will be written in this file. Below is a completed example.
②spec/system/articles_spec.rb
require 'rails_helper'
RSpec.describe "Articles", type: :system do
describe 'Article testing' 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 'mail address', with: company.email
fill_in 'password', with: company.password
click_button 'Login'
end
describe 'Sidebar test' do
context 'Check the display' do
it 'Article search is displayed' do
expect(page).to have_content "Article search"
expect(current_path).to eq corporate_articles_path
end
it 'Article registration is displayed' do
expect(page).to have_content "Article registration"
expect(current_path).to eq corporate_articles_path
end
end
end
describe 'Post test' do
context 'Transition to new article posting page' do
it 'Transition' do
click_on 'Register an article'
expect(page).to have_content "Post new article"
expect(current_path).to eq new_corporate_article_path
end
end
context 'Check the display' do
before do
visit new_corporate_article_path
end
it 'Article top image form is displayed' do
expect(page).to have_field 'article[image]'
end
it 'The genre select box is displayed' do
expect(page).to have_select 'Genre'
end
it 'The listing status select box is displayed' do
expect(page).to have_select 'Posting status'
end
it 'Article title form is displayed' do
expect(page).to have_field 'Article title'
end
it 'Article content form is displayed' do
expect(page).to have_field 'Article content'
end
it 'Article posting button is displayed' do
expect(page).to have_button 'Post an article'
end
end
context 'Posting an article' do
before do
visit new_corporate_article_path
end
it 'Successful posting' do
select "Test genre", from: 'Genre'
select "Now posted", from: 'Posting status'
fill_in 'Article title', with: "RSpec is difficult"
fill_in 'Article content', with: "It ’s difficult, but I ’m happy if the test suite goes through and everything turns green."
click_button "Post an article"
expect(page).to have_content "I posted a new article."
end
it 'Posting fails' do
fill_in 'Article title', with: ""
click_button "Post an article"
expect(page).to have_content "The article was not saved due to the error."
end
end
end
describe 'Editing test' do
context 'Confirmation of transition to each screen' do
it 'You can transition to the article details screen' do
click_on article.title
expect(page).to have_content "Article details"
expect(current_path).to eq corporate_article_path(article)
end
it 'You can transition to the article edit screen' do
visit corporate_article_path(article) #Transition to the article details screen
click_on "To edit"
expect(page).to have_content "Article information editing"
expect(current_path).to eq edit_corporate_article_path(article)
end
end
context 'Confirmation of display and editing' do
before do
visit edit_corporate_article_path(article)
end
it 'Article top image form is displayed' do
expect(page).to have_field 'article[image]'
end
it 'The genre select box is displayed' do
expect(page).to have_select('Genre', selected: 'テストGenre')
end
it 'The listing status select box is displayed' do
expect(page).to have_select('Posting status', selected: 'Now posted')
end
it 'Article title form is displayed' do
expect(page).to have_field 'Article title', with: article.title
end
it 'Article content form is displayed' do
expect(page).to have_field 'Article content', with: article.body
end
it 'Article edit button is displayed' do
expect(page).to have_button 'Save your changes'
end
it 'Successful editing' do
select "Posting suspended"
fill_in 'Article title', with: "I will stop posting until I can write RSpec smoothly"
click_button 'Save your changes'
expect(page).to have_content 'The update of the article information is completed.'
expect(page).to have_content '[Current publication status: Posting suspended]'
expect(current_path).to eq corporate_article_path(article)
end
it 'Editing fails' do
fill_in 'Article title', with: ""
click_button 'Save your changes'
expect(page).to have_content "The article was not saved due to the error."
end
end
end
end
end
As I explained in the model specs, posting the article ⑴ There is a company, ⑵ There is a genre of articles, ⑶ Articles can be posted It has become a flow. Therefore, you can understand that a company exists and it is necessary to select a genre in advance to post an article. Note that the difference from the last time is that the data created by FactoryBot is saved using let, not an instance variable.
②spec/system/articles_spec.rb
context 'Posting an article' do
before do
visit new_corporate_article_path
end
it 'Successful posting' do
select "Test genre", from: 'Genre' # セレクトボックスからGenreを選択
select "Now posted", from: 'Posting status' # セレクトボックスからPosting status(Now posted or 掲載停止中)choose
fill_in 'Article title', with: "RSpec is difficult" #enter title
fill_in 'Article content', with: "It ’s difficult, but I ’m happy if the test suite goes through and everything turns green." # Article contentを入力
click_button "Post an article" # Post an articleボタンを押下
expect(page).to have_content "I posted a new article."
end
it 'Posting fails' do
fill_in 'Article title', with: ""
click_button "Post an article"
expect(page).to have_content "The article was not saved due to the error."
end
end
In the above code example, the page where the post form is displayed is first transitioned to in the before block. Next, post form 1. Select genre, 2. Select publication status, 3. Enter title, 4. Enter article content and press the post button.
** Stumble point: hugging: "Select select box" **
In the selection of the select box above, it is described as select" test genre ", from:'genre'
.
Perhaps it's not a stumbling block if you do it normally, but I've had a lot of trouble here as well, so I'll share it.
The cause of the stumbling was that the ** label tag was not written correctly **, and I could not select the select box well.
Here's how to write my wrong label tag.
Ruby:corporate/articles/new.html.erb
<%= f.label :Genre%><br>
<%= f.collection_select :genre_id, Genre.all, :id, :genre_name, include_blank: "--Please select--" %>
The description of <% = f.label: Genre%>
is incorrect.
It is displayed without any problem on the browser, but when I check it with the verification tool
For some reason, the for attribute is a mixture of English and Japanese (for = "article_genre"), such as <label for =" article_genre "> genre </ label>
. I can't seem to make a good choice.
Here is how to write the correct label tag.
Ruby:corporate/articles/new.html.erb
<%= f.label :genre_id, "Genre" %><br>
<%= f.collection_select :genre_id, Genre.all, :id, :genre_name, include_blank: "--Please select--" %>
** Added on October 2, 2020 ** Regarding how to write the label tag above, it seems better to put the translated version in a YAML file and display it in the view instead of writing it solidly in the view in the form of "genre". I will describe it in this way once, but I will fix it later.
The display when viewed with the verification tool is as <label for =" article_genre_id "> genre </ label>
.
Rather than describing the test, it may be a plain part because the view was written incorrectly in the first place, but when I received advice in the comments of the second article, I finally understood the cause.
There may not be many people who have a hard time with this, but for the time being, this article [HTML] Why should you add the for attribute to the label tag? Thorough explanation of how to use! Explains the label tag in detail.
Probably, if ** for attribute contains a proper value (genre_id in this case), it will be linked programmatically to the input element **. I learned a lot. If for some reason the test doesn't pass like me, you may want to check it with Chrome's verification tool!
The test that fails the rest of the posts and the test of editing the article are basically the same as before, so please write it with reference to the completed code!
The test is finally over! This DM / notification test ends the core function test. let's do our best! By the way, FactoryBot is not used in this test. Below is an example of the completed code.
①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 'DM test' do
before do
visit new_user_session_path
fill_in 'mail address', with: user.email
fill_in 'password', with: user.password
click_button 'Login'
expect(page).to have_content 'You are now logged.'
end
context 'Check the display' do
it 'You can transition to the expert list' do
click_on 'Expert'
expect(current_path).to eq companies_path
end
it 'A button to move to the company details screen and start DM is displayed' 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 'Start DM'
end
end
context 'Individual side: Sending a message' do
before do
visit company_path(company) #Move to company details screen
click_on 'Start DM'
end
it 'You can enter the chat room and the submission form will be displayed' do
expect expect(page).to have_field 'Please enter a message'
end
it 'Can send messages' do
fill_in 'Please enter a message', with: 'Test message'
click_button 'Send'
expect(page).to have_content 'Test message'
end
it 'After sending a message, the sending history is added to the DM list screen' do
fill_in 'Please enter a message', with: 'Test message'
click_button 'Send'
expect(page).to have_content 'Test message' #Messages in chat rooms
visit rooms_path
expect(page).to have_content 'Test message' #DM list screen message
expect(page).to have_link 'View message'
end
end
context 'Corporate side: Receive-send message(reply)' do
before do
#Send a message on the individual side
visit company_path(company)
click_on 'Start DM'
fill_in 'Please enter a message', with: 'Test message'
click_button 'Send'
logout(user)
#Corporate login
visit new_company_session_path
fill_in 'mail address', with: company.email
fill_in 'password', with: company.password
click_button 'Login'
expect(page).to have_content 'You are now logged.'
end
it 'The number of notifications is displayed in the header' do
expect(page).to have_content '1 Notification'
end
it 'You can move to the notification list screen from the link, and you can check the receipt of messages from individual users.' do
click_on 'notification'
expect(page).to have_content 'notification'
expect(page).to have_content 'There is a message from Test Taro'
end
it 'You can enter the chat room from the link and see the message you received' do
click_on 'notification'
click_on 'message'
expect expect(page).to have_content 'Test message'
end
it 'Can send messages' do
click_on 'notification'
click_on 'message'
fill_in 'Please enter a message', with: 'Reply to test message'
click_button 'Send'
expect(page).to have_content 'Reply to test message'
end
end
end
end
①spec/system/rooms_spec.rb
context 'Individual side: Sending a message' do
before do
visit company_path(company) #Move to company details screen
click_on 'Start DM'
end
it 'You can enter the chat room and the submission form will be displayed' do
expect expect(page).to have_field 'Please enter a message'
end
it 'Can send messages' do
fill_in 'Please enter a message', with: 'Test message'
click_button 'Send'
expect(page).to have_content 'Test message'
end
it 'After sending a message, the sending history is added to the DM list screen' do
fill_in 'Please enter a message', with: 'Test message'
click_button 'Send'
expect(page).to have_content 'Test message' #Messages in chat rooms
visit rooms_path
expect(page).to have_content 'Test message' #DM list screen message
expect(page).to have_link 'View message'
end
end
I think there are some particularly difficult points.
** In the test'Can send message'**
fill_in'Enter message', with:'Test message'
⇨ Enter the string test message in the text boxclick_button'Send'
⇨ Press the send buttonIt has become a flow.
** In the test "After sending a message, the transmission history is added to the DM list screen" **
visit rooms_path
⇨ Move to DM list screenIt has become a flow.
The above is the DM test on the individual side. Next, I would like to explain the test on the corporate side. See the code example below.
①spec/system/rooms_spec.rb
context 'Corporate side: Receive-send message(reply)' do
before do
#Send a message on the individual side
visit company_path(company)
click_on 'Start DM'
fill_in 'Please enter a message', with: 'Test message'
click_button 'Send'
logout(user)
#Corporate login
visit new_company_session_path
fill_in 'mail address', with: company.email
fill_in 'password', with: company.password
click_button 'Login'
expect(page).to have_content 'You are now logged.'
end
it 'The number of notifications is displayed in the header' do
expect(page).to have_content '1 Notification'
end
it 'You can move to the notification list screen from the link, and you can check the receipt of messages from individual users.' do
click_on 'notification'
expect(page).to have_content 'notification'
expect(page).to have_content 'There is a message from Test Taro'
end
it 'You can enter the chat room from the link and see the message you received' do
click_on 'notification'
click_on 'message'
expect expect(page).to have_content 'Test message'
end
it 'Can send messages' do
click_on 'notification'
click_on 'message'
fill_in 'Please enter a message', with: 'Reply to test message'
click_button 'Send'
expect(page).to have_content 'Reply to test message'
end
end
This is not particularly difficult either. First, in the before block, describe up to the point where the individual side sent a message and then the corporation logged in. **'The number of notifications is displayed in the header' ** In the test ʻExpect (page) .to have_content '1 Notifications'` ⇨ When you log in, check that the header shows the number of notifications according to the number of messages and a link to the notification list.
**'You can move to the notification list screen from the link and confirm the reception of messages from individual users' ** In the test ʻExpect (page) .to have_content'There is a message from Test Taro'` ⇨ When you move to the notification list screen, you can check who the message is from.
All you have to do is enter the chat room, check if a message is coming, and see if you can send (reply) a message from here as well.
This is the DM / notification test.
This time, we have summarized the testing of article posting, editing, DM, and notification by system specifications. This completes the system specs that I wrote in two parts! I wrote it as a review of myself, but I thought again that there are still improvements. I would like to make small corrections so that beginners who see this do not say "What is this, I don't understand!".
At first I had a lot of trouble with things I didn't understand, but the other day's study session for beginners RSpec Beginners !! I've been able to write tests myself more than when I participated in, and if I'm asked something, I'll be able to tell people a little.
We would like to thank Mr. Ito (@jnchito) for providing such an opportunity and all the people who invited us.
Also, although it's childish, I hope this article will be of some help to RSpec beginners. Thank you for watching until the end!
[Introduction to RSpec that can be used, Part 4 "Any browser operation is free! Reverse Capybara Dictionary"](https://qiita.com/jnchito/items/607f956263c38a5fec24 "Introduction to RSpec that can be used, Part 4" Any browser operation is free ! Reverse Capybara Dictionary "") [HTML] Why should you add the for attribute to the label tag? Thorough explanation of how to use!