[RUBY] [R Spec on Rails] So schreiben Sie Testcode für Anfänger von Anfängern

Dieses Mal werde ich zusammenfassen, wie ich den Testcode mit RSpec schreibe, um mein Verständnis des Testcodes zu vertiefen. Als ich den Testcode zum ersten Mal schrieb, erinnere ich mich, dass ich ihn geschrieben habe, indem ich ihn nachgeahmt habe, ohne zu wissen, warum ich den Testcode brauchte. Deshalb möchte ich zum Anfang zurückkehren und ihn so detailliert wie möglich schreiben. Eine ausführliche Erläuterung der Begriffe entfällt übrigens. Bitte lesen Sie den Artikel, der leicht verständlich zusammengefasst ist. Empfohlen => Einführung in RSpec, das verwendet werden kann, Teil 1 "Grundlegende Syntax und nützliche Funktionen von RSpec verstehen"

1. Warum benötigen Sie Testcode?

Dies dient dazu, die Qualität zu gewährleisten, indem die Funktionsprüfung der Anwendung dem Computer überlassen wird. Wenn eine Person den Vorgang manuell überprüft, kann dies zu einer Auslassung führen. Sie können menschliches Versagen beseitigen, indem Sie den Test automatisieren. Selbst wenn es andere Änderungen in den Spezifikationen gibt, müssen Sie nur die Änderungen überprüfen, damit Sie sich die Mühe sparen können, alle Tests ab 1 neu zu starten.

2. Was ist Rspec?

RSpec ist ein Juwel, mit dem Testcode für Ruby on Rails geschrieben wird. Ruby on Rails hat eine Standardtestfunktion namens Minitest, aber in der eigentlichen Entwicklungssite mit Rails scheint das Testen mit RSpec der Mainstream zu sein, daher verwende ich es als Übung.

3. Informationen zum Inhalt der diesmal zu testenden Anwendung

Dieses Mal haben wir drei Modelle für Benutzer, Raum und Nachricht in unserer eigenen Chat-Anwendung, und wir werden den Fluss des Testcodes für jedes Benutzermodell schreiben. Der Unit-Test-Code des Benutzermodells dient dazu, zu überprüfen, ob die Benutzerregistrierung korrekt ist und ob die Set-Validierung funktioniert.

4. Entwicklungsumgebung

・ MacOS Catalina 10.15.6 ・ Ruby 2.6.5 ・ Schienen 6.0.3 ・ Gem FactoryBot ・ Gem RSpec ・ Gem Faker

5. Vorgehensweise

5-0. Vorbereitung

Zuerst werden wir FactoryBot, RSpec und Faker vorstellen.

Gemfile


(Abkürzung)
group :development, :test do
  #Dieses Mal verwenden wir die neueste Version, daher geben wir die Version nicht an
  gem 'rspec-rails'
  #Mit FactoryBot wird automatisch eine Instanz erstellt. Das musst du nicht, aber das ist auch eine Übung.
  gem 'factory_bot_rails'
  #Faker generiert zufällig einen Namen und ein Passwort für Sie. Dies ist auch praktisch, also gewöhnen wir uns daran.
  gem 'faker'
end
(Abkürzung)

Führen Sie die Bundle-Installation durch

% bundle install
5-1. RSpec-Einstellungen

Lassen Sie uns die notwendigen Dateien für RSpec erstellen.

% rails g rspec:install

Ich denke, Sie haben einige Dateien erstellt.

create  .rspec
create  spec
create  spec/spec_helper.rb
create  spec/rails_helper.rb

Schreiben Sie Folgendes in Ihre .rspec-Datei

.rspec


--require spec_helper
--format documentation

Mit dieser Beschreibung können Sie das Ergebnis des Testcodes auf dem Terminal sehen. Führen Sie den folgenden Befehl aus, um eine Datei zum Testen des erforderlichen Benutzermodells zu erstellen. Dieses Mal wird nur das Benutzermodell verwendet, aber die Vorgehensweise ist für andere Modelle dieselbe.

% rails g rspec:model user

Sie sollten jetzt die erforderlichen Dateien haben.

create  spec/models/user_spec.rb
invoke  factory_bot
create spec/factories/users.rb

Wenn die Datei users.rb nicht erstellt wird, erstellen Sie das Fabrikverzeichnis im Spezifikationsverzeichnis und die Datei users.rb darin.

5-2. FactoryBot-Einstellungen

Wir werden FactoryBot einrichten. Schreiben Sie Folgendes in spec / factories / users.rb.

spec/factories/users.rb



#Dies ist eine Beschreibung für die Verwendung von FactoryBot
FactoryBot.define do
  #Benutzerklasse durch Schreiben wie folgt(Benutzermodell)Das wird automatisch beurteilt
  factory :user do
    #Generieren Sie zufällig den Inhalt, der im Namen gespeichert werden soll
    name {Faker::Name.first_name}
    #E-Mail automatisch generieren
    email {Faker::Internet.email}
    #Für das Passwort müssen Sie denselben Wert zweimal eingeben, auch zur Bestätigung. Generieren Sie den Wert also zufällig als Variable
    #Das Erstellungskennwort muss mindestens 6 Zeichen lang sein, also min_Stellen Sie die Länge auf 6 Zeichen oder mehr ein
    password = Faker::Internet.password(min_length: 6)
    #Legen Sie das Passwort und die oben im Passwortbestätigungsrahmen festgelegte Variable fest
    password {password}
    password_confirmation {password}
  end
end

Dieses Mal sind nur Name, E-Mail-Adresse und Passwort verfügbar. Wenn jedoch andere Elemente für die Validierung festgelegt sind, fügen Sie diese bitte hinzu. Damit sind die FactoryBot-Einstellungen abgeschlossen. Lassen Sie uns die Konsole im Terminal starten und überprüfen.

% rails c

[1] pry(main)> FactoryBot.build(:user)
=> #<User id: nil, name: "颯", email: "[email protected]", created_at: nil, updated_at: nil>

Wenn es so ausgegeben wird, ist es in Ordnung! (Der Name und die E-Mail werden zufällig von Faker generiert, sodass sie sich jedes Mal ändern.)

5-3. Testcode schreiben

Schreiben wir nun den Testcode. Überprüfen Sie zunächst die Datei user_spec.rb.

spec/models/spec_user.rb


require 'rails_helper'

RSpec.describe User, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
+ describe '#create' do
+   before do
+     @user = FactoryBot.build(:user)
+   end
+ end
end

Zunächst werde ich so schreiben. Da beschreiben bedeutet zu erklären, beschreibt es, worum es beim Test geht. Erstellen Sie eine Benutzerinstanz basierend auf dem Inhalt, der in der Datei spec / factories / users.rb im nachfolgenden Block festgelegt wurde, und machen Sie sie zu einer Variablen. Da es danach in einem anderen Bereich verwendet wird, handelt es sich um eine Instanzvariable.

Von hier aus werde ich eine kurze Erklärung in den Code schreiben

spec/models/spec_user.rb


RSpec.describe User, type: :model do
  #Erstellen Sie einen neuen Benutzer(Anmeldung)Weil es ein Test ist#Ich erschaffe
  describe '#create' do
    # spec/factories/user.Machen Sie den Inhalt von rb zu einer aufrufenden Variablen
    #Keine lokale Variable, da sie einen anderen Bereich hat@Um es zu einer Instanzvariablen zu machen
    before do
      @user = FactoryBot.build(:user)
    end
    #Beschreiben Sie den Zustand / die Situation im Kontext
    context 'Wenn Sie sich als Benutzer registrieren können' do
      #Beschreiben Sie den darin zu testenden Gegenstand
      it 'name, email, password, password_Wenn die Bestätigung korrekt eingegeben wurde, können Sie sich neu registrieren' do
        #Wenn die von FactoryBot erstellten Benutzerinformationen korrekt sind, werden sie nicht validiert_Bestehen Sie den Test mit gültig
        expect(@user).to be_valid
      end
    end
  end
end

Die RSpec-Testcodesyntax setzt häufig eine Bedingung nach dem Kontext. Stellen Sie sich den Inhalt dieses Kontexts als den if (true) -Teil der if ~ else-Anweisung vor. Daher wird davon ausgegangen, dass der Inhalt auch als Benutzer registriert werden kann. Beschreiben Sie dann die erwarteten Testergebnisse in der Form Expect (X) .to Y. Dieser Bereich wird im folgenden Artikel sehr leicht verständlich erläutert.

Referenz => Einführung in RSpec, die verwendet werden kann, Teil 1 "Grundlegende Syntax und nützliche Funktionen von RSpec verstehen" Dieses Mal erwarte ich das Ergebnis, dass die in der Instanzvariablen enthaltenen Benutzerinformationen ohne Validierung neu registriert werden können. Schreiben Sie die Details zu dem, was Sie dazwischen testen möchten. Für andere ist es wünschenswert zu sehen, worum es bei dem Testobjekt geht.

Lassen Sie uns überprüfen, ob das Testergebnis korrekt ist. Geben Sie den folgenden Befehl in das Terminal ein.

% bundle exec rspec spec/models/user_spec.rb 

Wenn Folgendes an das Terminal ausgegeben wird, wird es korrekt registriert.

1 examples, 0 failure

Als nächstes werden wir den Fall testen, in dem eine Registrierung nicht möglich ist. Übrigens gibt es im Test ein normales System und ein abnormales System, und der ursprüngliche Zweck, wie das Registrieren des Benutzers, der zuerst getestet hat, ist das normale System, und umgekehrt ist es aufgrund der Validierung nicht möglich, sich zu registrieren. Es wird als abnormales System bezeichnet, um sicherzustellen, dass das oben Genannte nicht erreicht werden kann. Danach werden wir das abnormale System testen.

Schreiben wir wie folgt.

spec/models/user_spec.rb


 (Abkürzung)
    context 'Wenn Sie sich als Benutzer registrieren können' do
      #Beschreiben Sie den darin zu testenden Gegenstand
      it 'name, email, password, password_Wenn die Bestätigung korrekt eingegeben wurde, können Sie sich neu registrieren' do
        #Wenn die von FactoryBot erstellten Benutzerinformationen korrekt sind, werden sie nicht validiert_Bestehen Sie den Test mit gültig
        expect(@user).to be_valid
      end
    end

    context 'Wenn Sie sich nicht als Benutzer registrieren können' do
      #Es wurde getestet, dass die Registrierung aufgrund einer Validierung nicht möglich ist, wenn versucht wird, sich ohne Eingabe eines Benutzernamens zu registrieren
      it 'Kann nicht registriert werden, wenn der Name leer ist' do
        #Aktualisieren Sie den Benutzernamen auf leer
        @user.name = nil
        # valid?Beurteilen Sie, ob die Validierung bestanden wurde, und generieren Sie eine Fehlermeldung, wenn die Validierung nicht bestanden wurde
        @user.valid? 
        # @user.errors.full_Fehlermeldung mit Meldungen anzeigen
        #Beschreiben Sie die Fehlermeldung, die nach dem Einschließen angezeigt wird
        #Name kann, wenn Gerät nicht ins Japanische übersetzt ist'Ich denke, Sie werden die Fehlermeldung erhalten, dass sie leer ist
        expect(@user.errors.full_messages).to include("Bitte geben Sie einen Namen ein")
      end
    end

Kurz gesagt wird durch Setzen des Namens auf Null und Verwenden der gültigen? -Methode eine Fehlermeldung aufgrund der Validierung generiert. Wenn Gems 'Pry-Rails' installiert ist, schreiben Sie binding.pry nach user.valid?, Führen Sie den Testcode aus. Wenn der Prozess stoppt, geben Sie user.errors in die Konsole ein, und es tritt ein Fehler auf. Danach können Sie die Fehlermeldung auch überprüfen, indem Sie user.erros.full_messages eingeben. Übrigens, wenn sich die Zeichenfolge im Include des obigen Codes auch nur um ein Zeichen unterscheidet, wird die folgende Ausgabe ausgegeben und der Test wird nicht bestanden.

Failures:

1) User#create Wenn eine Benutzerregistrierung nicht möglich ist Eine Registrierung ist nicht möglich, wenn der Name leer ist
    Failure/Error: expect(@user.errors.full_messages).to include("Name can't be blank")
      expected ["Bitte geben Sie einen Namen ein"] to include "Name can't be blank"
    # ./spec/models/user_spec.rb:28:in `block (4 levels) in <top (required)>'

Dies bedeutet, dass ich erwartet habe, dass die Fehlermeldung "Name kann nicht leer sein" lautet, aber tatsächlich "Name eingeben". (Ich habe vergessen, dass das Gerät ins Japanische übersetzt wurde und einen Fehler gemacht hat ...) Wenn Sie die Fehleranweisung überprüfen, wird die tatsächliche Fehlermeldung nach der erwarteten Ausgabe ausgegeben. Wenn Sie diese also kopieren und einfügen, besteht der Test.

Dies ist der endgültige Code.

spec/models/user_spec.rb


require 'rails_helper'

#Beschreiben Sie, was der Test beschreibt
#Diesmal ist es ein Test des Benutzermodells, also wird es so sein
RSpec.describe User, type: :model do
  #Erstellen Sie einen neuen Benutzer(Anmeldung)Weil es ein Test ist#Ich erschaffe
  describe '#create' do
    # spec/factories/user.Machen Sie den Inhalt von rb zu einer aufrufenden Variablen
    #Keine lokale Variable, da sie einen anderen Bereich hat@Um es zu einer Instanzvariablen zu machen
    before do
      @user = FactoryBot.build(:user)
    end
    #Beschreiben Sie den Zustand / die Situation im Kontext
    context 'Wenn Sie sich als Benutzer registrieren können' do
      #Beschreiben Sie den darin zu testenden Gegenstand
      it 'name, email, password, password_Wenn die Bestätigung korrekt eingegeben wurde, können Sie sich neu registrieren' do
        #Wenn die von FactoryBot erstellten Benutzerinformationen korrekt sind, werden sie nicht validiert_Bestehen Sie den Test mit gültig
        expect(@user).to be_valid
      end
    end

    context 'Wenn Sie sich nicht als Benutzer registrieren können' do
      #Es wurde getestet, dass die Registrierung aufgrund einer Validierung nicht möglich ist, wenn versucht wird, sich ohne Eingabe eines Benutzernamens zu registrieren
      it 'Kann nicht registriert werden, wenn der Name leer ist' do
        #Aktualisieren Sie den Benutzernamen auf leer
        @user.name = nil
        # valid?Beurteilen Sie, ob die Validierung bestanden wurde, und generieren Sie eine Fehlermeldung, wenn die Validierung nicht bestanden wurde
        @user.valid? 
        # @user.errors.full_Fehlermeldung mit Meldungen anzeigen
        #Beschreiben Sie die Fehlermeldung, die nach dem Einschließen angezeigt wird
        #Name kann, wenn Gerät nicht ins Japanische übersetzt ist'Ich denke, Sie werden die Fehlermeldung erhalten, dass sie leer ist
        expect(@user.errors.full_messages).to include("Bitte geben Sie einen Namen ein")
      end

      it 'Kann nicht registriert werden, wenn die E-Mail leer ist' do
        @user.email = nil
        @user.valid?
        expect(@user.errors.full_messages).to include("Bitte geben Sie ihre E-Mail-Adresse ein")
      end

      #Standardmäßig hat devise eine Validierung, dass derselbe Inhalt der Eindeutigkeit nicht registriert werden kann.
      it 'Dieselbe E-Mail kann nicht registriert werden, wenn sie bereits verwendet wird' do
        #Bereiten Sie zwei Benutzer vor, um die Eindeutigkeit zu bestätigen
        # @Benutzer speichern
        @user.save
        #Erstellen Sie einen zweiten Benutzer
        another_user = FactoryBot.build(:user)
        # another_E-Mail des Benutzers@Aktualisieren Sie auf dieselbe E-Mail-Adresse wie der Benutzer
        another_user.email = @user.email
        another_user.valid?
        expect(another_user.errors.full_messages).to include("E-Mail ist bereits vorhanden")
      end

      it 'Kann nicht registriert werden, wenn das Passwort leer ist' do
        @user.password = nil
        @user.valid?
        expect(@user.errors.full_messages).to include("Bitte geben Sie Ihr Passwort ein", "Passwort (zur Bestätigung) und Passworteingabe stimmen nicht überein")
      end

      #Standardmäßig verfügt devise über eine Validierung, die Sie nur registrieren können, wenn das Kennwort mindestens 6 Zeichen enthält
      it 'Kann nicht registriert werden, wenn das Passwort 6 Zeichen oder weniger enthält' do
        #Setzen Sie das Passwort auf 5 Zeichen
        @user.password = "12345"
        @user.password_confirmation = "12345"
        @user.valid?
        expect(@user.errors.full_messages).to include("Bitte geben Sie das Passwort mit mindestens 6 Zeichen ein")
      end:tired_face:

      it 'Passwort auch wenn das Passwort korrekt ist_Kann nicht registriert werden, wenn die Bestätigung nicht übereinstimmt' do
        # #Wenn Sie dies auf Null setzen, wird der Test nicht bestanden.""Muss sein
        @user.password_confirmation = ""
        @user.valid?
        expect(@user.errors.full_messages).to include("Passwort (zur Bestätigung) und Passworteingabe stimmen nicht überein")
      end
    end
  end
end

Was ich anfangs nicht dachte, war, dass ich mich nicht registrieren konnte, wenn meine E-Mail-Adresse mit der anderer Benutzer identisch war. Der Punkt war, zuerst zwei Benutzer zu erstellen und die erste E-Mail-Adresse auf den gleichen Wert wie die zweite E-Mail-Adresse zu aktualisieren, absichtlich den gleichen.

Ein weiterer Punkt ist der letzte Teil: "Auch wenn das Passwort korrekt ist, kann es nur registriert werden, wenn die password_confirmation übereinstimmt." Wenn Sie die Kennwortbestätigung auf Null setzen, funktioniert sie nicht. Sie müssen daher explizit angeben, dass sie mit "" leer ist. Im Gegenteil, andere Namen und E-Mails können "" sein.

Das Obige ist der Inhalt des Unit-Test-Codes des diesmal implementierten Benutzermodells. Ich habe versucht, es so detailliert wie möglich zu schreiben, aber es ist ziemlich lang geworden, aber beim nächsten Mal möchte ich es leichter verständlich machen. Als nächstes wünschte ich, ich könnte über den Integrationstestcode schreiben. Ich würde mich freuen, wenn Sie auf Fehler oder verwirrende Teile hinweisen könnten.

Referenz => FactoryBot Github Referenz => RSpec Github Referenz => Faker Github

Recommended Posts

[R Spec on Rails] So schreiben Sie Testcode für Anfänger von Anfängern
Wie schreibe ich Rails
So schreiben Sie Testcode mit Basic-Zertifizierung
[Für Rails-Anfänger] Zusammenfassung der Verwendung von RSpec (Überblick)
[Ruby on Rails] Wie schreibe ich eine Enumeration auf Japanisch?
[Rails] Testcode mit Rspec
Wie schreibe ich Rails Seed
Wie schreibe ich Rails Routing
[RSpec] Testen von Fehlermeldungen, die unabhängig von Shoulda-Matchers festgelegt wurden
Erklärung von Ruby on Rails für Anfänger ④ ~ Informationen zu Benennungsregeln und zur Verwendung von form_Tag ~
Verwendung von Ruby on Rails
So stellen Sie Bootstrap auf Rails bereit
[Rails] Wie schreibe ich eine Ausnahmebehandlung?
So schreiben Sie leicht verständlichen Code [Zusammenfassung 3]
Ein Muss für Anfänger! Eine konkrete Möglichkeit, ein X-Code-Projekt auf Github zu verwalten
Verstehen Sie die Codeabdeckung mit Rspec, dem Ruby on Rails-Testframework
[Ruby on Rails] So vermeiden Sie das Erstellen unnötiger Routen für die Entwicklung
[Rails] Unit-Testcode für das Benutzermodell
Führen Sie RSpec ein und schreiben Sie den Unit-Test-Code
[Ruby on Rails] Test mit RSpec anzeigen
[Ruby on Rails] Controller-Test mit RSpec
[Ruby] Wie man Slice für Anfänger benutzt
[Ruby on Rails] Verwendung von redirect_to
Schreiben Sie Code, der schwer zu testen ist
[Ruby on Rails] Modelltest mit RSpec
Erklärung von Ruby auf Schienen für Anfänger ①
[SpringBoot] So schreiben Sie einen Controller-Test
[Für Anfänger] So debuggen Sie mit Eclipse
Ein Muss für Anfänger! Spezifische Methode zum Verwalten von X-Code-Projekten auf Github ②
So legen Sie verschiedene Quell- / Zielversionen für Produktionscode und Testcode fest
(Für Anfänger) [Rails] Zeitsparende Technik! So installieren und verwenden Sie slim
[Rspec] Ablauf von der Einführung von Rspec bis zum Schreiben von Unit-Test-Code für das Modell
[Rails] So bestimmen Sie das Ziel anhand von "Rails-Routen"
Schienen: Wie man eine Rechenaufgabe schön schreibt
[Java] So testen Sie, ob es in JUnit null ist
[Rails] Wie schreibe ich, wenn ich eine Unterabfrage mache?
So geben Sie die von Rails erstellte CSV in S3 aus
JUnit 5: Wie man Testfälle in enum schreibt
[Rails] So implementieren Sie einen Unit-Test eines Modells
[Für Anfänger] So implementieren Sie die Löschfunktion
Einführung in Rspec, ein Testframework für Ruby on Rails
So trennen Sie .scss nach Controller in Rails
Wie man Code schreibt, der objektorientiertes Ruby denkt
[Rails MySQL] So setzen Sie die Datenbank auf Heroku zurück