RSpec - Panduan Pantas

RSpec - Pengenalan

RSpec ialah rangka kerja ujian unit untuk bahasa pengaturcaraan Ruby. RSpec berbeza daripada kerangka xUnit tradisional seperti JUnit kerana RSpec adalah alat pembangunan yang didorong oleh Perilaku. Apa ini bermakna, ujian yang ditulis dalam fokus RSpec pada "tingkah laku" aplikasi yang diuji. RSpec tidak memberi penekanan kepada, bagaimana aplikasi berfungsi tetapi sebaliknya bagaimana ia berkelakuan, dengan kata lain, apa aplikasi sebenarnya.

Persekitaran RSpec

Pertama sekali, anda perlu memasang Ruby pada komputer anda. Walau bagaimanapun, jika anda belum selesai sebelum ini, anda boleh memuat turun dan memasang Ruby dari laman utama Ruby - Ruby .

Sekiranya anda memasang Ruby pada Windows, anda sepatutnya mempunyai pemasang Ruby untuk Windows di sini - http://www.rubyinstaller.org

Untuk tutorial ini, anda hanya perlu editor teks, seperti Notepad dan konsol baris perintah. Contoh-contoh di sini akan menggunakan cmd.exe pada Windows.

Untuk menjalankan cmd.exe, klik pada menu Mula dan ketik "cmd.exe", kemudian tekan kekunci Return.

Pada command prompt di tetingkap cmd.exe anda, ketik perintah berikut untuk melihat versi Ruby yang anda gunakan -

ruby -v

Anda harus melihat output di bawah yang kelihatan seperti ini -

ruby 2.2.3p173 (2015-08-18 revision 51636) [x64-mingw32]

Contoh-contoh dalam tutorial ini akan menggunakan Ruby 2.2.3 tetapi mana-mana versi Ruby yang lebih tinggi daripada 2.0.0 akan cukup. Seterusnya, kita perlu memasang permata RSpec untuk pemasangan Ruby anda. Permata adalah perpustakaan Ruby yang boleh anda gunakan dalam kod anda sendiri. Untuk memasang permata, anda perlu menggunakan perintah permata .

Mari pasang permata Rspec sekarang. Kembali ke tetingkap cmd.exe anda dan taipkan yang berikut -

gem install rspec

Anda sepatutnya mempunyai senarai permata yang tergantung yang telah dipasang, ini adalah permata yang permata rspec perlu berfungsi dengan betul. Pada akhir output, anda harus melihat sesuatu yang kelihatan seperti ini -

Done installing documentation for diff-lcs, rspec-support, rspec-mocks,
   rspec-expectations, rspec-core, rspec after 22 seconds 
6 gems installed

Jangan bimbang, jika output anda tidak kelihatan sama. Juga, jika anda menggunakan komputer Mac atau Linux, anda mungkin perlu menjalankan permata memasang perintah rspec dengan menggunakan sudo atau menggunakan alat seperti HomeBrew atau RVM untuk memasang permata rspec.

Hello World

Untuk bermula, mari buat direktori (folder) untuk menyimpan fail RSpec kami. Dalam tetingkap cmd.exe anda, taipkan yang berikut -

cd \

Kemudian taipkan -

mkdir rspec_tutorial

Dan akhirnya, taipkan -

cd rspec_tutorial

Dari sini, kami akan mencipta direktori lain yang bernama, lakukan dengan menaip -

mkdir spec

Kami akan menyimpan fail RSpec kami dalam folder ini. Fail-fail RSpec dikenali sebagai "spesifikasi". Jika ini seolah-olah mengelirukan kepada anda, anda boleh memikirkan fail spec sebagai fail ujian. RSpec menggunakan istilah "spec" yang merupakan bentuk ringkas untuk "spesifikasi".

Oleh kerana, RSpec adalah alat ujian BDD, matlamatnya adalah untuk memberi tumpuan kepada apa yang dilakukan aplikasi dan sama ada ia mengikuti spesifikasi atau tidak. Dalam perkembangan tingkah laku, spesifikasi sering diterangkan dari segi "Cerita Pengguna". RSpec direka untuk menjelaskan sama ada kod sasaran berkelakuan dengan betul, dengan kata lain mengikuti spesifikasi.

Mari kembali ke kod Hello Hello kami. Buka editor teks dan tambahkan kod berikut -

class HelloWorld

   def say_hello 
      "Hello World!"
   end
   
end

describe HelloWorld do 
   context “When testing the HelloWorld class” do 
      
      it "should say 'Hello World' when we call the say_hello method" do 
         hw = HelloWorld.new 
         message = hw.say_hello 
         expect(message).to eq "Hello World!"
      end
      
   end
end

Seterusnya, simpan ini ke fail bernama hello_world_spec.rb dalam folder spec yang anda buat di atas. Sekarang kembali ke tetingkap cmd.exe anda, jalankan arahan ini -

rspec spec spec\hello_world_spec.rb

Apabila arahan selesai, anda perlu melihat output yang kelihatan seperti ini -

Finished in 0.002 seconds (files took 0.11101 seconds to load) 
1 example, 0 failures

Tahniah, awak baru buat dan lari ujian unit RSpec pertama anda!

Dalam bahagian seterusnya, kami akan terus membincangkan sintaks fail RSpec.

RSpec - Syntax Asas

Mari lihat dengan teliti kod contoh HelloWorld kami. Pertama sekali, sekiranya ia tidak jelas, kami sedang menguji fungsi kelas HelloWorld . Ini sudah tentu, adalah kelas yang sangat sederhana yang mengandungi hanya satu kaedah say_hello () .

Berikut ialah kod RSpec sekali lagi -

describe HelloWorld do 
   context “When testing the HelloWorld class” do 
      
      it "The say_hello method should return 'Hello World'" do 
         hw = HelloWorld.new 
         message = hw.say_hello 
         expect(message).to eq "Hello World!" 
      end
      
   end 
end

Kata kunci yang diterangkan

Penjelasan perkataan adalah kata kunci RSpec. Ia digunakan untuk menentukan "Kumpulan Contoh". Anda boleh memikirkan "Kumpulan Contoh" sebagai koleksi ujian. Kata kunci menerangkan boleh mengambil nama kelas dan / atau hujah rentetan. Anda juga perlu lulus hujah blok untuk menerangkan , ini akan mengandungi ujian individu, atau seperti yang diketahui dalam RSpec, "Contoh". Blok itu hanya blok Ruby yang ditetapkan oleh kata kunci Ruby lakukan / berakhir .

Konteks kata kunci

Kata kunci konteks sama dengan menggambarkan . Ia juga boleh menerima nama kelas dan / atau hujah rentetan. Anda harus menggunakan blok dengan konteks juga. Idea konteks adalah bahawa ia menyertakan ujian jenis tertentu.

Sebagai contoh, anda boleh menentukan kumpulan Contoh dengan konteks yang berbeza seperti ini -

context “When passing bad parameters to the foobar() method” 
context “When passing valid parameters to the foobar() method” 
context “When testing corner cases with the foobar() method”

Kata kunci konteks tidak wajib, tetapi ia membantu untuk menambah lebih banyak maklumat tentang contoh yang terkandung.

Kata kunci itu

Perkataan itu adalah kata kunci RSpec lain yang digunakan untuk menentukan "Contoh". Satu contoh pada dasarnya adalah ujian atau kes ujian. Sekali lagi, seperti penjelasan dan konteks, ia menerima kedua-dua nama kelas dan argumen rentetan dan harus digunakan dengan hujah blok, yang ditetapkan dengan do / end . Dalam kes itu , adalah kebiasaan untuk melewati hujah rentetan dan blok. Hujah rentetan sering menggunakan perkataan "should" dan dimaksudkan untuk menggambarkan apa tingkah laku khusus yang harus terjadi di dalam blok itu . Dalam erti kata lain, ia menerangkan bahawa hasil yang diharapkan adalah untuk Contoh.

Perhatikan ia menghalang dari Contoh HelloWorld kami -

it "The say_hello method should return 'Hello World'" do

Rentetan itu jelaskan apa yang harus berlaku apabila kita memanggil menyalahgunakan kelas HelloWorld. Ini sebahagian daripada falsafah RSpec, contohnya bukan sekadar ujian, ia juga merupakan satu spesifikasi (spec). Dalam erti kata lain, Contoh kedua-dua dokumen dan menguji tingkah laku yang diharapkan dari kod Ruby anda.

Kata kunci yang diharapkan

Kata kunci yang diharapkan digunakan untuk menentukan "Harapan" dalam RSpec. Ini adalah langkah pengesahan yang kami periksa, bahawa keadaan yang dijangka khusus telah dipenuhi.

Dari contoh HelloWorld kami, kami ada -

expect(message).to eql "Hello World!"

Idea dengan mengharapkan kenyataan adalah bahawa mereka membaca seperti bahasa Inggeris biasa. Anda boleh mengatakan ini dengan kuat sebagai "Jangkakan mesej pembolehubah untuk menyamai tali 'Hello World'". Ideanya ialah deskriptif dan mudah dibaca, walaupun bagi pihak berkepentingan bukan teknikal seperti pengurus projek.

The to keyword

Kata kunci tersebut digunakan sebagai sebahagian daripada kenyataan yang diharapkan . Ambil perhatian bahawa anda juga boleh menggunakan not_to kata kunci untuk menyatakan yang bertentangan, apabila anda ingin Harapan itu salah. Anda dapat melihat bahawa untuk digunakan dengan titik, mengharapkan (mesej) .to, kerana ia sebenarnya hanya kaedah Ruby biasa. Malah, semua kata kunci RSpec benar-benar hanya kaedah Ruby.

The eql keyword

Kata kunci eql adalah kata kunci RSpec khusus yang disebut Matcher. Anda menggunakan Pencocokan untuk menyatakan jenis keadaan yang anda uji benar (atau palsu).

Dalam kenyataan HelloWorld kami mengharapkan , jelas bahawa eql bermakna persamaan rentetan. Perhatikan bahawa, terdapat pelbagai jenis operator kesetaraan di Ruby dan akibatnya berbeza Pencocokan yang sepadan dalam RSpec. Kami akan meneroka pelbagai jenis Pencocokan di bahagian yang kemudian.

Spesifikasi Penulisan RSpec -

Dalam bab ini, kami akan membuat kelas Ruby baru, simpan dalam failnya sendiri dan buat fail spec berasingan untuk menguji kelas ini.

Pertama, dalam kelas baru kami, ia dipanggil StringAnalyzer . Ia adalah kelas mudah yang anda fikirkan, menganalisis rentetan. Kelas kami hanya mempunyai satu kaedah has_vowels? yang mana nama namanya, mengembalikan benar jika rentetan mengandungi vokal dan palsu jika tidak. Inilah pelaksanaan untuk StringAnalyzer -

class StringAnalyzer 
   def has_vowels?(str) 
      !!(str =~ /[aeio]+/i) 
   end 
end

Jika anda mengikuti seksyen HelloWorld, anda mencipta folder bernama C: \ rspec_tutorial \ spec.

Padamkan fail hello_world.rb jika anda memilikinya dan simpan kod StringAnalyzer di atas ke fail bernama string_analyzer.rb dalam folder C: \ rspec_tutorial \ spec.

Inilah sumber untuk fail spec kami untuk menguji StringAnalyzer -

require 'string_analyzer' 

describe StringAnalyzer do 
   context "With valid input" do 
      
      it "should detect when a string contains vowels" do 
         sa = StringAnalyzer.new 
         test_string = 'uuu' 
         expect(sa.has_vowels? test_string).to be true 
      end 
		
      it "should detect when a string doesn't contain vowels" do 
         sa = StringAnalyzer.new 
         test_string = 'bcdfg' 
         expect(sa.has_vowels? test_string).to be false
      end 
      
   end 
end

Simpan ini dalam direktori spec yang sama, memberikan nama string_analyzer_test.rb.

Dalam tetingkap cmd.exe anda, cd ke folder C: \ rspec_tutorial dan jalankan arahan ini: dir spec

Anda harus melihat perkara berikut -

Direktori C: \ rspec_tutorial \ spec

09/13/2015 08:22 AM  <DIR>    .
09/13/2015 08:22 AM  <DIR>    ..
09/12/2015 11:44 PM                 81 string_analyzer.rb
09/12/2015 11:46 PM              451 string_analyzer_test.rb

Sekarang kita akan menjalankan ujian kami, jalankan arahan ini: rspec spec

Apabila anda lulus nama folder ke rspec , ia menjalankan semua fail spec di dalam folder. Anda harus melihat hasil ini -

No examples found.

Finished in 0 seconds (files took 0.068 seconds to load)
0 examples, 0 failures

Alasan bahawa ini berlaku adalah, secara lalai, rspec hanya menjalankan fail yang namanya berakhir dalam "_spec.rb". Namakan semula string_analyzer_test.rb ke string_analyzer_spec.rb. Anda boleh melakukannya dengan mudah dengan menjalankan arahan ini -

ren spec\string_analyzer_test.rb string_analyzer_spec.rb

Sekarang, jalankan semula rspec lagi, anda harus melihat output yang kelihatan seperti ini -

F.
Failures:

   1) StringAnalyzer With valid input should detect when a string contains vowels
      Failure/Error: expect(sa.has_vowels? test_string).to be true 
         expected true
            got false
      # ./spec/string_analyzer_spec.rb:9:in `block (3 levels) in <top (required)>'

Finished in 0.015 seconds (files took 0.12201 seconds to load)
2 examples, 1 failure

Failed examples:
rspec ./spec/string_analyzer_spec.rb:6 # StringAnalyzer With valid 
   input should detect when a string contains vowels
Do you see what just happened? Our spec failed because we have a bug in 
   StringAnalyzer. The bug is simple to fix, open up string_analyzer.rb
   in a text editor and change this line:
!!(str =~ /[aeio]+/i)
to this:
!!(str =~ /[aeiou]+/i)

Sekarang, simpan perubahan yang baru dibuat di string_analyizer.rb dan jalankan perintah spec rspec sekali lagi, sekarang anda akan melihat output yang kelihatan seperti -

..
Finished in 0.002 seconds (files took 0.11401 seconds to load)
2 examples, 0 failures

Tahniah, contoh (ujian) dalam fail spec anda kini lulus. Kami menetapkan pepijat dalam ungkapan biasa yang mempunyai kaedah vokal tetapi ujian kami jauh dari lengkap.

Adalah masuk akal untuk menambah lebih banyak contoh yang menguji pelbagai jenis rentetan input dengan kaedah vokal yang telah ada.

Jadual berikut menunjukkan beberapa permutasi yang boleh ditambah dalam Contoh baru (ia menyekat)

Rentetan input Penerangan Hasil yang dijangkakan dengan has_vowels?
'aaa', 'eee', 'iii', 'o' Hanya satu vokal dan tiada surat lain. benar
'abcefg' 'Sekurang-kurangnya satu vokal dan beberapa konsonan' benar
'mnklp' Hanya konsonan. salah
'' Rentetan kosong (tiada huruf) salah
'abcde55345 & ??' Aksara vokal, konsonan, nombor dan aksara tanda baca. benar
'423432 %%% ^ &' Nombor dan aksara tanda baca sahaja. salah
'AEIOU' Vokal kes atas sahaja. benar
'AeiOuuuA' Kes atas dan vokal yang lebih rendah sahaja. benar
'AbCdEfghI' Huruf besar dan huruf kecil dan huruf konsonan. benar
'BCDFG' Konsonan kes atas sahaja. salah
'' Watak spasi sahaja. salah

Terserah kepada anda untuk membuat keputusan, contoh yang akan ditambah kepada fail spec anda. Terdapat banyak syarat untuk diuji, anda perlu menentukan subset syarat apa yang paling penting dan ujian kod anda yang terbaik.

Perintah rspec menawarkan banyak pilihan yang berbeza, untuk melihat mereka semua, taip rspec -help. Jadual berikut menyenaraikan pilihan yang paling popular dan menerangkan apa yang mereka lakukan.

Sr.No. Pilihan / bendera & Penerangan
1

-I PATH

Menambah PATH ke muatan (memerlukan) jalan yang digunakan oleh rspec apabila mencari fail sumber Ruby.

2

-r, - dapatkan PATH

Menambah fail sumber tertentu yang diperlukan dalam spec anda. fail (s).

3

- cepat-cepat

Dengan pilihan ini, rspec akan berhenti menjalankan spesifikasi selepas Contoh pertama gagal. Secara lalai, rspec menjalankan semua fail spec tertentu, tidak kira berapa banyak kegagalan ada.

4

-f, --format FORMATTER

Pilihan ini membolehkan anda menentukan format output yang berbeza. Lihat bahagian di Formatters untuk maklumat lanjut tentang format output.

5

-o, - keluar FILE

Pilihan ini mengarahkan rspec untuk menulis hasil ujian ke fail output FILE dan bukannya keluar standard.

6

-c, --color

Membolehkan warna dalam output rspec. Keputusan Contoh yang berjaya akan dipaparkan dalam teks hijau, kegagalan akan mencetak dalam teks merah.

7

-b, --backtrace

Memaparkan backtraces kesilapan penuh dalam output rspec.

8

-w, --warnings

Memaparkan amaran Ruby dalam output rspec.

9

-P, --PATTERN pattern

Muatkan dan jalankan fail spec yang sepadan dengan pola PATTERN. Sebagai contoh, jika anda lulus -p "* .rb", rspec akan menjalankan semua fail Ruby, bukan hanya yang berakhir di "_spec.rb".

10

-e, - misalnya STRING

Pilihan ini mengarahkan rspec untuk menjalankan semua Contoh yang mengandungi teks STRING dalam deskripsi mereka.

11

-t, --tag TAG

Dengan pilihan ini, rspec hanya akan menjalankan contoh yang mengandungi tag TAG. Ambil perhatian bahawa TAG dinyatakan sebagai simbol Ruby. Lihat bahagian pada Tag RSpec untuk maklumat lanjut.

RSpec - Pencocokan

Sekiranya anda mengingati contoh Hello World asalnya, ia mengandungi garis yang kelihatan seperti ini -

expect(message).to eq "Hello World!"

Kata kunci eql adalah RSpec "matcher". Di sini, kami akan memperkenalkan jenis-jenis perlawanan yang lain di RSpec.

Penyamaan Keadilan / Identiti

Pencocokan untuk menguji kesamaan objek atau nilai.

Penyokong Penerangan Contoh
persamaan Lulus bila sebenar == dijangka mengharapkan (sebenarnya)
eql Pas apabila actual.eql? (Dijangka) menjangkakan (sebenar)
menjadi Melalui realiti sebenar (dijangka) menjangkakan (sebenar) untuk dijangka
sama Juga berlalu ketika actual.equal? (Dijangka) mengharapkan (sebenarnya)

Contoh

describe "An example of the equality Matchers" do 

   it "should show how the equality Matchers work" do 
      a = "test string" 
      b = a 
      
      # The following Expectations will all pass 
      expect(a).to eq "test string" 
      expect(a).to eql "test string" 
      expect(a).to be b 
      expect(a).to equal b 
   end
   
end

Apabila kod di atas dilaksanakan, ia akan menghasilkan output berikut. Bilangan saat mungkin sedikit berbeza pada komputer anda -

.
Finished in 0.036 seconds (files took 0.11901 seconds to load)
1 example, 0 failures

Penyandingan Perbandingan

Pencocokan untuk membandingkan nilai.

Penyokong Penerangan Contoh
> Lulus ketika sebenar> dijangka mengharapkan (sebenarnya). untuk dijangka> dijangka
> = Pas apabila sebenar> = dijangka mengharapkan (sebenarnya). untuk menjadi> = dijangka
< Lulus apabila <diharapkan mengharapkan (sebenarnya). untuk dijangka <diharapkan
<= Lulus apabila <= jangkaan sebenar mengharapkan (sebenarnya). menjadi <= dijangka
be_between inclusive Lulus ketika sebenarnya <= min dan> = max mengharapkan (sebenarnya). untuk be_between (min, max) .inclusive
be_between eksklusif Lulus apabila sebenarnya <min dan> max jangkaan (sebenar). untuk be_between (min, max) .exclusive
perlawanan Melewati apabila padanan sebenar ungkapan biasa menjangkakan (sebenar) untuk perlawanan (/ regex /)

Contoh

describe "An example of the comparison Matchers" do

   it "should show how the comparison Matchers work" do
      a = 1
      b = 2
      c = 3		
      d = 'test string'
      
      # The following Expectations will all pass
      expect(b).to be > a
      expect(a).to be >= a 
      expect(a).to be < b 
      expect(b).to be <= b 
      expect(c).to be_between(1,3).inclusive 
      expect(b).to be_between(1,3).exclusive 
      expect(d).to match /TEST/i 
   end
   
end

Apabila kod di atas dilaksanakan, ia akan menghasilkan output berikut. Bilangan saat mungkin sedikit berbeza pada komputer anda -

. 
Finished in 0.013 seconds (files took 0.11801 seconds to load) 
1 example, 0 failures

Kelas / Jenis Pencocokan

Pencocokan untuk menguji jenis atau kelas objek.

Penyokong Penerangan Contoh
be_instance_of Lulus apabila sebenar adalah contoh kelas yang dijangka. mengharapkan (sebenarnya) .to be_instance_of (Diharapkan)
be_kind_of Lulus apabila sebenar adalah contoh kelas yang dijangka atau mana-mana kelas induknya. mengharapkan (sebenarnya) .to be_kind_of (Diharapkan)
bertindak balas terhadap Melalui apabila menjawab sebenar kepada kaedah yang ditentukan. mengharapkan (sebenarnya). untuk membalas_to (dijangka)

Contoh

describe "An example of the type/class Matchers" do
 
   it "should show how the type/class Matchers work" do
      x = 1 
      y = 3.14 
      z = 'test string' 
      
      # The following Expectations will all pass
      expect(x).to be_instance_of Fixnum 
      expect(y).to be_kind_of Numeric 
      expect(z).to respond_to(:length) 
   end
   
end

Apabila kod di atas dilaksanakan, ia akan menghasilkan output berikut. Bilangan saat mungkin sedikit berbeza pada komputer anda -

. 
Finished in 0.002 seconds (files took 0.12201 seconds to load) 
1 example, 0 failures

Pemegang Benar / Salah / Tiada

Pencocokan untuk menguji sama ada nilai adalah benar, salah atau tidak.

Penyokong Penerangan Contoh
jadi jujur Lulus ketika sebenar == benar mengharapkan (sebenarnya) untuk menjadi kenyataan
menjadi palsu Pas apabila sebenarnya == palsu menjangkakan (sebenarnya). menjadi palsu
be_truthy Pas apabila sebenarnya tidak salah atau tidak mengharapkan (sebenarnya) .to be_truthy
be_falsey Melalui bila sebenarnya palsu atau tidak menjangkakan (sebenar) .to be_falsey
be_nil Pas apabila sebenarnya tidak ada menjangkakan (sebenarnya) .to be_nil

Contoh

describe "An example of the true/false/nil Matchers" do
   it "should show how the true/false/nil Matchers work" do
      x = true 
      y = false 
      z = nil 
      a = "test string" 
      
      # The following Expectations will all pass
      expect(x).to be true 
      expect(y).to be false 
      expect(a).to be_truthy 
      expect(z).to be_falsey 
      expect(z).to be_nil 
   end 
end

Apabila kod di atas dilaksanakan, ia akan menghasilkan output berikut. Bilangan saat mungkin sedikit berbeza pada komputer anda -

. 
Finished in 0.003 seconds (files took 0.12301 seconds to load) 
1 example, 0 failures

Ralat Pencocokan

Pencocokan untuk ujian, apabila blok kod menimbulkan ralat.

Penyokong Penerangan Contoh
raise_error (ErrorClass) Lulus apabila blok menimbulkan ralat jenis ErrorClass. mengharapkan {block}. untuk raise_error (ErrorClass)
raise_error ("mesej ralat") Lulus apabila blok menimbulkan ralat dengan mesej "mesej ralat". mengharapkan {block}. untuk raise_error ("mesej ralat")
raise_error (ErrorClass, "mesej ralat") Lulus apabila blok menimbulkan ralat jenis ErrorClass dengan mesej "mesej ralat" mengharapkan {block}. untuk raise_error (ErrorClass, "mesej ralat")

Contoh

Simpan kod berikut ke fail dengan nama error_matcher_spec.rb dan jalankan dengan perintah ini - rspec error_matcher_spec.rb .

describe "An example of the error Matchers" do 
   it "should show how the error Matchers work" do 
      
      # The following Expectations will all pass 
      expect { 1/0 }.to raise_error(ZeroDivisionError)
      expect { 1/0 }.to raise_error("divided by 0") 
      expect { 1/0 }.to raise_error("divided by 0", ZeroDivisionError) 
   end 
end

Apabila kod di atas dilaksanakan, ia akan menghasilkan output berikut. Bilangan saat mungkin sedikit berbeza pada komputer anda -

. 
Finished in 0.002 seconds (files took 0.12101 seconds to load) 
1 example, 0 failures

RSpec - Ujian Doubles

Dalam bab ini, kami akan membincangkan Doubles RSpec, yang juga dikenali sebagai RSpec Mocks. Double adalah objek yang boleh "berdiri" untuk objek lain. Anda mungkin tertanya-tanya apa yang dimaksudkan dengan tepat dan mengapa anda memerlukannya.

Katakan anda sedang membina sebuah aplikasi untuk sekolah dan anda mempunyai kelas yang mewakili bilik darjah pelajar dan kelas lain untuk pelajar, iaitu anda mempunyai kelas Kelas dan kelas Pelajar. Anda perlu menulis kod untuk salah satu kelas terlebih dahulu, jadi katakanlah itu, mulakan dengan kelas Kelas -

class ClassRoom 
   def initialize(students) 
      @students = students 
   end 
   
   def list_student_names 
      @students.map(&:name).join(',') 
   end 
end

Ini adalah kelas yang mudah, ia mempunyai satu kaedah list_student_names, yang mengembalikan rentetan koma nama pelajar. Sekarang, kami ingin mencipta ujian untuk kelas ini tetapi bagaimana kita melakukannya jika kita belum membuat kelas Pelajar? Kami memerlukan ujian Double.

Juga, jika kita mempunyai kelas "dummy" yang berkelakuan seperti objek Pelajar maka ujian ClassRoom kami tidak akan bergantung kepada kelas Pelajar. Kami panggil pengasingan ujian ini.

Jika ujian ClassRoom kami tidak bergantung pada mana-mana kelas lain, maka apabila ujian gagal, kami dapat mengetahui dengan segera bahawa terdapat bug dalam kelas ClassRoom kami dan bukan kelas lain. Perlu diingat bahawa, di dunia nyata, anda mungkin membina sebuah kelas yang perlu berinteraksi dengan kelas lain yang ditulis oleh orang lain.

Di sinilah RSpec Doubles (mengejek) menjadi berguna. Kaedah list_student_names kami memanggil kaedah nama pada setiap Objek Pelajar dalam pemboleh ubah ahli-ahli @ mereka. Oleh itu, kita memerlukan Double yang menerapkan kaedah nama.

Berikut ialah kod untuk ClassRoom bersama-sama dengan Contoh RSpec (ujian), tetapi perhatikan bahawa tiada Kelas Pelajar yang ditakrifkan -

class ClassRoom 
   def initialize(students) 
      @students = students 
   end
   
   def list_student_names 
      @students.map(&:name).join(',') 
   end 
end

describe ClassRoom do 
   it 'the list_student_names method should work correctly' do 
      student1 = double('student') 
      student2 = double('student') 
      
      allow(student1).to receive(:name) { 'John Smith'} 
      allow(student2).to receive(:name) { 'Jill Smith'} 
      
      cr = ClassRoom.new [student1,student2]
      expect(cr.list_student_names).to eq('John Smith,Jill Smith') 
   end 
end

Apabila kod di atas dilaksanakan, ia akan menghasilkan output berikut. Masa berlalu mungkin sedikit berbeza di komputer anda -

. 
Finished in 0.01 seconds (files took 0.11201 seconds to load) 
1 example, 0 failures

Seperti yang anda lihat, menggunakan double test membolehkan anda menguji kod anda walaupun ia bergantung pada kelas yang tidak ditentukan atau tidak tersedia. Juga, ini bermakna apabila terdapat kegagalan ujian, anda boleh memberitahu dengan segera bahawa ia adalah kerana isu dalam kelas anda dan bukan kelas yang ditulis oleh orang lain.

RSpec - Ranting

Jika anda sudah membaca bahagian di Doubles RSpec (aka Mocks), maka anda sudah melihat Rangkaian RSpec. Dalam RSpec, sebuah rintisan sering dipanggil Kaedah Rintis, ia adalah kaedah khas yang "berdiri" untuk kaedah yang sedia ada, atau kaedah yang masih belum wujud.

Berikut adalah kod dari bahagian pada Doubles RSpec -

class ClassRoom 
   def initialize(students) 
      @students = students 
   End
   
   def list_student_names 
      @students.map(&:name).join(',') 
   end 
end 

describe ClassRoom do 
   it 'the list_student_names method should work correctly' do 
      student1 = double('student') 
      student2 = double('student') 
      
      allow(student1).to receive(:name) { 'John Smith'}
      allow(student2).to receive(:name) { 'Jill Smith'} 
      
      cr = ClassRoom.new [student1,student2]
      expect(cr.list_student_names).to eq('John Smith,Jill Smith') 
   end 
end

Dalam contoh kami, kaedah allow () memberikan kaedah kaedah yang kita perlukan untuk menguji kelas ClassRoom. Dalam kes ini, kita memerlukan objek yang akan bertindak seperti contoh kelas Pelajar, tetapi kelas itu sebenarnya tidak wujud (belum). Kami tahu bahawa kelas Pelajar perlu menyediakan satu nama () kaedah dan kami menggunakan allow () untuk mencipta stub kaedah untuk nama ().

Satu perkara yang perlu diperhatikan ialah, sintaks RSpec telah berubah sedikit sejak bertahun-tahun. Dalam versi lama RSpec, kaedah kaedah di atas akan ditakrifkan seperti ini -

student1.stub(:name).and_return('John Smith') 
student2.stub(:name).and_return('Jill Smith')

Mari kita ambil kod di atas dan gantikan dua baris () dengan sintaks RSpec lama -

class ClassRoom 
   def initialize(students) 
      @students = students 
   end 
   
   def list_student_names 
      @students.map(&:name).join(',') 
   end 
	
end 

describe ClassRoom do 
   it 'the list_student_names method should work correctly' do 
      student1 = double('student') 
      student2 = double('student')
      
      student1.stub(:name).and_return('John Smith')
      student2.stub(:name).and_return('Jill Smith') 
      
      cr = ClassRoom.new [student1,student2] 
      expect(cr.list_student_names).to eq('John Smith,Jill Smith') 
   end 
end

Anda akan melihat output ini apabila anda melaksanakan kod di atas -

.
Deprecation Warnings:

Using `stub` from rspec-mocks' old `:should` syntax without explicitly 
   enabling the syntax is deprec 

ated. Use the new `:expect` syntax or explicitly enable `:should` instead. 
   Called from C:/rspec_tuto 

rial/spec/double_spec.rb:15:in `block (2 levels) in <top (required)>'.
If you need more of the backtrace for any of these deprecations 
   to identify where to make the necessary changes, you can configure 

`config.raise_errors_for_deprecations!`, and it will turn the 
   deprecation warnings into errors, giving you the full backtrace.

1 deprecation warning total

Finished in 0.002 seconds (files took 0.11401 seconds to load)
1 example, 0 failures

Sudah disarankan agar anda menggunakan sintaks baru membenarkan () apabila anda perlu membuat stub kaedah dalam contoh RSpec anda, tetapi kami telah menyediakan gaya lama di sini supaya anda akan mengenalinya jika anda melihatnya.

RSpec - Hooks

Apabila anda menulis ujian unit, seringkali mudah untuk menjalankan kod persediaan dan pemadaman sebelum dan selepas ujian anda. Kod persediaan ialah kod yang mengkonfigurasi atau "menetapkan" syarat untuk ujian. Kod pemadaman melakukan pembersihan, ia memastikan bahawa persekitaran berada dalam keadaan yang konsisten untuk ujian berikutnya.

Secara umumnya, ujian anda harus bebas dari satu sama lain. Apabila anda menjalankan seluruh ujian dan salah seorang daripada mereka gagal, anda ingin yakin bahawa ia gagal kerana kod yang sedang ujian mempunyai pepijat, bukan kerana ujian terdahulu meninggalkan persekitaran dalam keadaan yang tidak konsisten.

Cangkuk yang paling biasa digunakan di RSpec adalah sebelum dan selepas cangkuk. Mereka menyediakan cara untuk menentukan dan menjalankan kod persediaan dan teardown yang dibincangkan di atas. Mari kita pertimbangkan kod contoh ini -

class SimpleClass 
   attr_accessor :message 
   
   def initialize() 
      puts "\nCreating a new instance of the SimpleClass class" 
      @message = 'howdy' 
   end 
   
   def update_message(new_message) 
      @message = new_message 
   end 
end 

describe SimpleClass do 
   before(:each) do 
      @simple_class = SimpleClass.new 
   end 
   
   it 'should have an initial message' do 
      expect(@simple_class).to_not be_nil
      @simple_class.message = 'Something else. . .' 
   end 
   
   it 'should be able to change its message' do
      @simple_class.update_message('a new message')
      expect(@simple_class.message).to_not be 'howdy' 
   end
end

Apabila anda menjalankan kod ini, anda akan mendapat output berikut -

Creating a new instance of the SimpleClass class 
. 
Creating a new instance of the SimpleClass class 
. 
Finished in 0.003 seconds (files took 0.11401 seconds to load) 
2 examples, 0 failures

Mari kita lihat dengan lebih dekat apa yang berlaku. Kaedah sebelum (: masing-masing) adalah di mana kita menentukan kod persediaan. Apabila anda lulus: setiap argumen, anda mengarahkan kaedah sebelumnya untuk menjalankan sebelum setiap contoh dalam Kumpulan Contoh anda iaitu kedua-dua ia menyekat di dalam blok terangkan dalam kod di atas.

Dalam baris: @simple_class = SimpleClass.new, kita membuat contoh baru dari kelas SimpleClass dan menyerahkannya kepada pembolehubah contoh objek. Apa yang anda mungkin tertanya-tanya? RSpec mencipta kelas khas di belakang tabir dalam skop blok menerangkan. Ini membolehkan anda menetapkan nilai kepada pemboleh ubah contoh kelas ini, yang anda boleh mengakses dalam blok tersebut dalam Contoh anda. Ini juga memudahkan menulis kod bersih dalam ujian kami. Sekiranya setiap ujian (Contoh) memerlukan contoh SimpleClass, kita boleh meletakkan kod tersebut sebelum cangkuk dan tidak perlu menambahkannya kepada setiap contoh.

Perhatikan bahawa baris "Membuat contoh baru dari kelas SimpleClass" ditulis ke konsol dua kali, ini menunjukkan bahawa, sebelum cangkuk dipanggil di setiap blok itu .

Seperti yang telah kami sebutkan, RSpec juga mempunyai cangkuk dan kedua-dua sebelum dan selepas cangkuk boleh diambil: semuanya sebagai hujah. Cangkuk selepas akan berjalan selepas sasaran yang ditetapkan. Yang: semua sasaran bermakna bahawa cangkuk akan berjalan sebelum / selepas semua Contoh. Berikut adalah contoh mudah yang menggambarkan apabila setiap cangkuk dipanggil.

describe "Before and after hooks" do 
   before(:each) do 
      puts "Runs before each Example" 
   end 
   
   after(:each) do 
      puts "Runs after each Example" 
   end 
   
   before(:all) do 
      puts "Runs before all Examples" 
   end 
   
   after(:all) do 
      puts "Runs after all Examples"
   end 
   
   it 'is the first Example in this spec file' do 
      puts 'Running the first Example' 
   end 
   
   it 'is the second Example in this spec file' do 
      puts 'Running the second Example' 
   end 
end

Apabila anda menjalankan kod di atas, anda akan melihat output ini -

Runs before all Examples 
Runs before each Example 
Running the first Example 
Runs after each Example 
.Runs before each Example 
Running the second Example 
Runs after each Example 
.Runs after all Examples

RSpec - Tags

Tags RSpec menyediakan cara mudah untuk menjalankan ujian khusus dalam fail spec anda. Secara lalai, RSpec akan menjalankan semua ujian dalam fail spec yang dijalankan, tetapi anda hanya perlu menjalankan subset daripada mereka. Katakan anda mempunyai beberapa ujian yang berjalan dengan sangat cepat dan anda telah membuat perubahan pada kod aplikasi anda dan anda hanya perlu menjalankan ujian cepat, kod ini akan menunjukkan cara melakukannya dengan Tag RSpec.

describe "How to run specific Examples with Tags" do 
   it 'is a slow test', :slow = > true do 
      sleep 10 
      puts 'This test is slow!' 
   end 
   
   it 'is a fast test', :fast = > true do 
      puts 'This test is fast!' 
   end 
end

Sekarang, simpan kod di atas dalam fail baru yang disebut tag_spec.rb. Dari baris arahan, jalankan arahan ini: rspec --tag slow tag_spec.rb

Anda akan melihat output ini -

Jalankan pilihan: termasuk {: slow => true}

This test is slow! 
. 
Finished in 10 seconds (files took 0.11601 seconds to load) 
1 example, 0 failures

Kemudian, jalankan arahan ini: rspec --tag tag_spec.rb cepat

Anda akan melihat output ini -

Run options: include {:fast = >true} 
This test is fast! 
. 
Finished in 0.001 seconds (files took 0.11201 seconds to load) 
1 example, 0 failures

Seperti yang anda lihat, Tags RSpec menjadikannya sangat mudah untuk subset ujian!

RSpec - Subjek

Salah satu kekuatan RSpec ialah menyediakan banyak cara untuk menulis ujian, ujian bersih. Apabila ujian anda pendek dan tidak runcit, ia menjadi lebih mudah untuk memberi tumpuan kepada kelakuan yang diharapkan dan bukan pada butir-butir bagaimana ujian itu ditulis. Subjek RSpec adalah satu lagi pintasan yang membolehkan anda menulis ujian mudah mudah.

Pertimbangkan kod ini -

class Person 
   attr_reader :first_name, :last_name 
   
   def initialize(first_name, last_name) 
      @first_name = first_name 
      @last_name = last_name 
   end 
end 

describe Person do 
   it 'create a new person with a first and last name' do
      person = Person.new 'John', 'Smith'
      
      expect(person).to have_attributes(first_name: 'John') 
      expect(person).to have_attributes(last_name: 'Smith') 
   end 
end

Ia sebenarnya cukup jelas, tetapi kami boleh menggunakan ciri subjek RSpec untuk mengurangkan jumlah kod dalam contohnya. Kami melakukan itu dengan menggerakkan instansasi objek orang ke dalam garis terperinci.

class Person 
   attr_reader :first_name, :last_name 
   
   def initialize(first_name, last_name) 
      @first_name = first_name 
      @last_name = last_name 
   end 
	
end 

describe Person.new 'John', 'Smith' do 
   it { is_expected.to have_attributes(first_name: 'John') } 
   it { is_expected.to have_attributes(last_name: 'Smith') }
end

Apabila anda menjalankan kod ini, anda akan melihat output ini -

.. 
Finished in 0.003 seconds (files took 0.11201 seconds to load) 
2 examples, 0 failures

Perhatikan, berapa banyak contoh kod kedua yang lebih mudah. Kami mengambil yang ia blok dalam contoh pertama dan menggantikannya dengan dua blok yang akhirnya memerlukan kod kurang dan sama seperti jelas.

RSpec - Helpers

Kadangkala contoh RSpec anda memerlukan cara mudah untuk berkongsi kod yang boleh diguna semula. Cara terbaik untuk mencapainya adalah dengan Helpers. Para pembantu pada dasarnya adalah kaedah Ruby biasa yang anda kongsi di seluruh contoh. Untuk menggambarkan faedah menggunakan pembantu, mari kita pertimbangkan kod ini -

class Dog 
   attr_reader :good_dog, :has_been_walked 
   
   def initialize(good_or_not) 
      @good_dog = good_or_not 
      @has_been_walked = false 
   end 
   
   def walk_dog 
      @has_been_walked = true 
   end 
end 

describe Dog do 
   it 'should be able to create and walk a good dog' do 
      dog = Dog.new(true) 
      dog.walk_dog 
      
      expect(dog.good_dog).to be true
      expect(dog.has_been_walked).to be true 
   end 
   
   it 'should be able to create and walk a bad dog' do 
      dog = Dog.new(false) 
      dog.walk_dog 

      expect(dog.good_dog).to be false
      expect(dog.has_been_walked).to be true 
 
   end 
end

Kod ini adalah jelas, tetapi selalu merupakan idea yang baik untuk mengurangkan kod berulang bila mungkin. Kita boleh mengambil kod di atas dan mengurangkan beberapa pengulangan ini dengan kaedah penolong yang disebut create_and_walk_dog ().

class Dog
   attr_reader :good_dog, :has_been_walked 
   
   def initialize(good_or_not)
      @good_dog = good_or_not 
      @has_been_walked = false 
   end 
   
   def walk_dog 
      @has_been_walked = true 
   end 
end 

describe Dog do 
   def create_and_walk_dog(good_or_bad)
      dog = Dog.new(good_or_bad)
      dog.walk_dog
      return dog 
   end 
   
   it 'should be able to create and walk a good dog' do
      dog = create_and_walk_dog(true)
      
      expect(dog.good_dog).to be true
      expect(dog.has_been_walked).to be true 
   end 
   
   it 'should be able to create and walk a bad dog' do 
      dog = create_and_walk_dog(false)
      
      expect(dog.good_dog).to be false
      expect(dog.has_been_walked).to be true 
   end 
end

Apabila anda menjalankan kod di atas, anda akan melihat output ini -

.. 
Finished in 0.002 seconds (files took 0.11401 seconds to load) 
2 examples, 0 failures

Seperti yang anda dapat lihat, kami dapat menolak logik untuk membuat dan berjalan objek anjing ke Helper yang membolehkan contoh kami menjadi lebih pendek dan bersih.

RSpec - Metadata

RSpec adalah alat yang fleksibel dan berkuasa. Fungsi Metadata dalam RSpec tidak terkecuali. Metadata biasanya merujuk kepada "data mengenai data". Dalam RSpec, ini bermakna data mengenai gambarajah , konteks dan blok tersebut .

Mari kita lihat contoh -

RSpec.describe "An Example Group with a metadata variable", :foo => 17 do 
   context 'and a context with another variable', :bar => 12 do 
      
      it 'can access the metadata variable of the outer Example Group' do |example| 
         expect(example.metadata[:foo]).to eq(17) 
      end
      
      it 'can access the metadata variable in the context block' do |example|  
         expect(example.metadata[:bar]).to eq(12) 
      end 
      
   end 
end

Apabila anda menjalankan kod di atas, anda akan melihat output ini -

.. 
Finished in 0.002 seconds (files took 0.11301 seconds to load) 
2 examples, 0 failures

Metadata menyediakan cara untuk menetapkan pembolehubah di pelbagai skop dalam fail RSpec anda. Pembolehubah contoh.metadata adalah hash Ruby yang mengandungi maklumat lain mengenai kumpulan Contoh dan Contoh anda.

Sebagai contoh, mari menulis semula kod di atas untuk kelihatan seperti ini -

RSpec.describe "An Example Group with a metadata variable", :foo => 17 do
   context 'and a context with another variable', :bar => 12 do 
      
      it 'can access the metadata variable in the context block' do |example|
         expect(example.metadata[:foo]).to eq(17) 
         expect(example.metadata[:bar]).to eq(12) 
         example.metadata.each do |k,v|
         puts "#{k}: #{v}"
      end
		
   end 
end 

Apabila kita menjalankan kod ini, kita melihat semua nilai dalam hash contoh.metadata -

.execution_result: #<RSpec::Core::Example::ExecutionResult:0x00000002befd50>
block: #<Proc:[email protected]:/rspec_tutorial/spec/metadata_spec.rb:7>
description_args: ["can access the metadata variable in the context block"]
description: can access the metadata variable in the context block
full_description: An Example Group with a metadata variable and a context 
   with another variable can access the metadata variable in the context block
described_class:
file_path: ./metadata_spec.rb
line_number: 7
location: ./metadata_spec.rb:7
absolute_file_path: C:/rspec_tutorial/spec/metadata_spec.rb
rerun_file_path: ./metadata_spec.rb
scoped_id: 1:1:2
foo: 17
bar: 12
example_group:
{:execution_result=>#<RSpec::Core::Example::ExecutionResult:
   0x00000002bfa0e8>, :block=>#<
   Proc:[email protected]:/rspec_tutorial/spec/metadata_spec.rb:2>, 
   :description_args=>["and a context with another variable"], 
	
   :description=>"and a context with another variable", 
   :full_description=>"An Example Group with a metadata variable
   and a context with another variable", :described_class=>nil, 
      :file_path=>"./metadata_spec.rb", 
		
   :line_number=>2, :location=>"./metadata_spec.rb:2", 
      :absolute_file_path=>"C:/rspec_tutorial/spec/metadata_spec.rb",
      :rerun_file_path=>"./metadata_spec.rb", 
		
   :scoped_id=>"1:1", :foo=>17, :parent_example_group=>
      {:execution_result=>#<
      RSpec::Core::Example::ExecutionResult:0x00000002c1f690>, 
      :block=>#<Proc:[email protected]:/rspec_tutorial/spec/metadata_spec.rb:1>
      , :description_args=>["An Example Group with a metadata variable"], 
		
   :description=>"An Example Group with a metadata variable", 
   :full_description=>"An Example Group with a metadata variable", 
	:described_class=>nil, :file_path=>"./metadata_spec.rb", 
   :line_number=>1, :location=>"./metadata_spec.rb:1",
   :absolute_file_path=>
	
   "C:/rspec_tutorial/spec/metadata_spec.rb", 
   :rerun_file_path=>"./metadata_spec.rb", 
   :scoped_id=>"1", :foo=>17}, 
   :bar=>12}shared_group_inclusion_backtrace: [] 
	
last_run_status: unknown .
.
Finished in 0.004 seconds (files took 0.11101 seconds to load) 
2 examples, 0 failures

Kemungkinan besar, anda tidak perlu menggunakan semua metadata ini, tetapi melihat nilai keterangan penuh -

Kumpulan Contoh dengan pemboleh ubah metadata dan konteks dengan pemboleh ubah lain boleh mengakses pembolehubah metadata dalam blok konteks.

Ini adalah satu kalimat yang dicipta dari huraian blok terangkan + perincian blok konteksnya yang terkandung + huraian untuk blok itu .

Apa yang menarik untuk diperhatikan di sini adalah, ketiga-tiga rentetan ini dibaca sama seperti kalimat Inggeris biasa. . . yang merupakan salah satu idea di belakang RSpec, mempunyai ujian yang sama seperti deskripsi bahasa Inggeris.

RSpec - Penapisan

Anda mungkin ingin membaca bahagian pada Metadata RSpec sebelum membaca bahagian ini kerana, ternyata, penapisan RSpec berdasarkan pada Metadata RSpec.

Bayangkan anda mempunyai fail spec dan mengandungi dua jenis ujian (Contoh): ujian fungsi positif dan ujian negatif (ralat). Mari kita tentukan mereka seperti ini -

RSpec.describe "An Example Group with positive and negative Examples" do 
   context 'when testing Ruby\'s build-in math library' do
      
      it 'can do normal numeric operations' do 
         expect(1 + 1).to eq(2) 
      end 
      
      it 'generates an error when expected' do
         expect{1/0}.to raise_error(ZeroDivisionError) 
      end
      
   end 
end

Sekarang, simpan teks di atas sebagai fail bernama 'filter_spec.rb' dan kemudian jalankan dengan arahan ini -

rspec filter_spec.rb

Anda akan melihat output yang kelihatan seperti ini -

.. 
Finished in 0.003 seconds (files took 0.11201 seconds to load) 
2 examples, 0 failures

Sekarang bagaimana jika, kami mahu menjalankan semula ujian positif dalam fail ini? Atau hanya ujian negatif? Kita boleh melakukannya dengan mudah dengan Penapis RSpec. Tukar kod di atas untuk ini -

RSpec.describe "An Example Group with positive and negative Examples" do 
   context 'when testing Ruby\'s build-in math library' do
      
      it 'can do normal numeric operations', positive: true do 
         expect(1 + 1).to eq(2) 
      end 
      
      it 'generates an error when expected', negative: true do 
         expect{1/0}.to raise_error(ZeroDivisionError) 
      end
      
   end 
end

Simpan perubahan anda kepada filter_spec.rb dan jalankan arahan yang sedikit berbeza ini -

rspec --tag positive filter_spec.rb

Sekarang, anda akan melihat output yang kelihatan seperti ini -

Run options: include {:positive=>true} 
. 
Finished in 0.001 seconds (files took 0.11401 seconds to load) 
1 example, 0 failures

Dengan menyatakan - tag positif, kami memberitahu RSpec untuk hanya menjalankan Contoh dengan: pembolehubah metadata positif ditakrifkan. Kita boleh melakukan perkara yang sama dengan ujian negatif dengan menjalankan perintah seperti ini -

rspec --tag negative filter_spec.rb

Perlu diingat bahawa ini hanyalah contoh, anda boleh menentukan penapis dengan mana-mana nama yang anda mahukan.

Formula RSpec

Formatters membenarkan RSpec untuk memaparkan output daripada ujian dengan cara yang berbeza. Mari buat fail RSpec baharu yang mengandungi kod ini -

RSpec.describe "A spec file to demonstrate how RSpec Formatters work" do 
   context 'when running some tests' do 
      
      it 'the test usually calls the expect() method at least once' do 
         expect(1 + 1).to eq(2) 
      end
      
   end 
end

Sekarang, simpan ini ke fail yang dipanggil formatter_spec.rb dan jalankan arahan RSpec ini -

rspec formatter_spec.rb

Anda harus melihat output yang kelihatan seperti ini -

. 
Finished in 0.002 seconds (files took 0.11401 seconds to load) 
1 example, 0 failures

Sekarang jalankan arahan yang sama tetapi kali ini menentukan formatter, seperti ini -

rspec --format progress formatter_spec.rb

Anda harus melihat keluaran yang sama kali ini -

. 
Finished in 0.002 seconds (files took 0.11401 seconds to load) 
1 example, 0 failures

Sebabnya ialah formatter "kemajuan" adalah formatter lalai. Mari cuba formatter yang berbeza seterusnya, cuba jalankan arahan ini -

rspec --format doc formatter_spec.rb

Kini anda perlu melihat output ini -

A spec file to demonstrate how RSpec Formatters work 
   when running some tests 
      the test usually calls the expect() method at least once
Finished in 0.002 seconds (files took 0.11401 seconds to load) 
1 example, 0 failures

Seperti yang anda lihat, keluarannya agak berbeza dengan formatter "doc". Format ini mempersembahkan output dalam gaya seperti dokumentasi. Anda mungkin tertanya-tanya apa pilihan ini apabila anda mengalami kegagalan dalam ujian (Contoh). Mari kita ubah kod dalam formatter_spec.rb untuk kelihatan seperti ini -

RSpec.describe "A spec file to demonstrate how RSpec Formatters work" do 
   context 'when running some tests' do 
      
      it 'the test usually calls the expect() method at least once' do 
         expect(1 + 1).to eq(1) 
      end
      
   end 
end

Harapan mengharapkan (1 + 1). Untuk persamaan (1) harus gagal. Simpan perubahan anda dan jalankan semula arahan di atas -

rspec --format progresster_spec.rb dan ingat, kerana formatter "kemajuan" adalah lalai, anda hanya boleh menjalankan: rspec formatter_spec.rb . Anda harus melihat output ini -

F 
Failures:
1) A spec file to demonstrate how RSpec Formatters work when running some tests 
the test usually calls the expect() method at least once
   Failure/Error: expect(1 + 1).to eq(1)
	
      expected: 1
         got: 2
			  
      (compared using ==)			  
   # ./formatter_spec.rb:4:in `block (3 levels) in <top (required)>'

Finished in 0.016 seconds (files took 0.11201 seconds to load)
1 example, 1 failure
Failed examples:

rspec ./formatter_spec.rb:3 # A spec file to demonstrate how RSpec 
   Formatters work when running some tests the test usually calls 
   the expect() method at least once

Sekarang, mari kita cuba formatter doc, jalankan arahan ini -

rspec --format doc formatter_spec.rb

Sekarang, dengan ujian yang gagal, anda harus melihat output ini -

A spec file to demonstrate how RSpec Formatters work
   when running some tests
      the test usually calls the expect() method at least once (FAILED - 1)
		
Failures:

1) A spec file to demonstrate how RSpec Formatters work when running some
   tests the test usually calls the expect() method at least once
   Failure/Error: expect(1 + 1).to eq(1)
	
   expected: 1
        got: 2
		  
   (compared using ==)
   # ./formatter_spec.rb:4:in `block (3 levels) in <top (required)>'
	
Finished in 0.015 seconds (files took 0.11401 seconds to load) 
1 example, 1 failure

Contoh Gagal

rspec ./formatter_spec.rb:3 # Satu fail spec untuk menunjukkan bagaimana Formula Kerja RSpec berfungsi semasa menjalankan beberapa ujian ujian biasanya memanggil kaedah expect () sekurang-kurangnya sekali.

Formula RSpec menawarkan keupayaan untuk mengubah cara paparan keputusan ujian, bahkan mungkin membuat Formatter tersuai anda sendiri, tetapi itu adalah topik yang lebih maju.

RSpec - Harapan

Apabila anda belajar RSpec, anda boleh membaca banyak tentang jangkaan dan mungkin sedikit mengelirukan pada mulanya. Terdapat dua butiran utama yang perlu anda ingat apabila anda melihat istilah Harapan -

  • Harapan hanyalah pernyataan dalam blok yang menggunakan kaedah expect () . Itu sahaja. Ia tidak lebih rumit daripada itu. Apabila anda mempunyai kod seperti ini: mengharapkan (1 + 1). Untuk eq (2) , anda mempunyai Harapan dalam contoh anda. Anda menjangkakan bahawa ungkapan 1 + 1 menilai kepada 2 . Perkataan itu penting walaupun sejak RSpec adalah rangka kerja ujian BDD. Dengan memanggil pernyataan ini Harapan, jelas bahawa kod RSpec anda menggambarkan "tingkah laku" dari kod yang ia uji. Idea ini ialah anda menyatakan bagaimana kod itu harus berkelakuan, dengan cara yang berbunyi seperti dokumentasi.

  • Sintaks Harapan agak baru. Sebelum kaedah jangkaan () diperkenalkan (kembali pada tahun 2012), RSpec menggunakan sintaks yang berbeza berdasarkan kaedah seharusnya () . Ramalan di atas ditulis seperti ini dalam sintaks lama: (1 + 1) .sekiranya eq (2) .

Anda mungkin menemui sintaks RSpec lama untuk Jangkaan apabila bekerja dengan kod lama yang lebih lama atau versi lama RSpec. Jika anda menggunakan sintaks lama dengan versi baru RSpec, anda akan melihat amaran.

Sebagai contoh, dengan kod ini -

RSpec.describe "An RSpec file that uses the old syntax" do
   it 'you should see a warning when you run this Example' do 
      (1 + 1).should eq(2) 
   end 
end

Apabila anda menjalankannya, anda akan mendapat output yang kelihatan seperti ini -

. Deprecation Warnings:

Using `should` from rspec-expectations' old `:should` 
   syntax without explicitly enabling the syntax is deprecated. 
   Use the new `:expect` syntax or explicitly enable 
	
`:should` with `config.expect_with( :rspec) { |c| c.syntax = :should }`
   instead. Called from C:/rspec_tutorial/spec/old_expectation.rb:3 :in 
   `block (2 levels) in <top (required)>'.

If you need more of the backtrace for any of these deprecations to
   identify where to make the necessary changes, you can configure 
`config.raise_errors_for_deprecations!`, and it will turn the deprecation 
   warnings into errors, giving you the full backtrace.

1 deprecation warning total 
Finished in 0.001 seconds (files took 0.11201 seconds to load) 
1 example, 0 failures

Kecuali anda dikehendaki menggunakan sintaks lama, sangat disyorkan bahawa anda menggunakan jangkaan () dan bukannya harus ().