RSpec vs Test :: Unit in Rails

15

Saya tidak pernah benar-benar yakin akan keuntungan yang Anda dapatkan dengan beralih ke RSpec dari Test :: Unit di Ruby on Rails (meskipun membaca dari waktu ke waktu tentang RSpec).

Ada apa dengan RSpec yang tampaknya sebagian besar proyek Rails menggunakannya?

(beberapa contoh kode dengan jelas menunjukkan keunggulan satu di atas yang lain akan sangat dihargai)

Paweł Gościcki
sumber
4
Hanya 1 tahun kemudian dan saya terlihat jijik di Test :: Unit ... RSpec FTW!
Paweł Gościcki
Duplikat Dekat pada StackOverflow: RSpec vs Test :: Unit dan RSpec vs Shoulda
sondra.kinsey

Jawaban:

13

Ini sebagian besar masalah selera, dan sebagian besar alat pengujian layak mendapatkan dukungan garam keduanya. Preferensi pribadi saya adalah untuk RSpec daripada Test :: Unit karena a) output dan tata letak tes berfokus pada apa yang seharusnya dilakukan oleh objek yang diuji (berlawanan dengan apa kode itu) dan b) mengatakan 'X should Y' lebih masuk akal bagi saya daripada 'menegaskan bahwa X berpredikat Y'.

Untuk memberikan Anda beberapa konteks untuk poin-poin di atas, berikut adalah perbandingan (cukup dibuat-buat) dari output / kode sumber dari dua tes unit yang setara secara fungsional, satu ditulis menggunakan RSpec dan yang lainnya menggunakan Test :: Unit.

Kode sedang diuji

class DeadError < StandardError; end

class Dog
  def bark
    raise DeadError.new "Can't bark when dead" if @dead
    "woof"
  end

  def die
    @dead = true
  end
end

Tes :: Unit

 require 'test/unit'
  require 'dog'

  class DogTest < Test::Unit::TestCase
    def setup
      @dog = Dog.new
    end

    def test_barks
      assert_equal "woof", @dog.bark    
    end

    def test_doesnt_bark_when_dead
      @dog.die
      assert_raises DeadError do
        @dog.bark
      end
    end
  end

RSpec

require 'rspec'
require 'dog'

describe Dog do
  before(:all) do
    @dog = Dog.new
  end

  context "when alive" do
    it "barks" do
      @dog.bark.should == "woof"
    end
  end

  context "when dead" do
    before do
      @dog.die
    end

    it "raises an error when asked to bark" do
      lambda { @dog.bark }.should raise_error(DeadError)
    end
  end
end

Test :: Unit output (setinggi yang saya bisa lakukan)

Ξ code/examples → ruby dog_test.rb --verbose
Loaded suite dog_test
Started
test_barks(DogTest): .
test_doesnt_bark_when_dead(DogTest): .

Finished in 0.004937 seconds.

Keluaran RSpec (formatter dokumentasi)

Ξ code/examples → rspec -fd dog_spec.rb 

Dog
  when alive
    barks
  when dead
    raises an error when asked to bark

Finished in 0.00224 seconds
2 examples, 0 failures

2 tests, 2 assertions, 0 failures, 0 errors

PS Saya pikir Berin (responden sebelumnya) menyatukan peran Mentimun (yang tumbuh dari proyek RSpec tetapi independen) dan RSpec. Mentimun adalah alat untuk pengujian penerimaan otomatis dalam gaya BDD, sedangkan RSpec adalah pustaka kode untuk pengujian yang dapat, dan, digunakan pada tingkat unit, integrasi dan fungsional. Karenanya menggunakan RSpec tidak menghalangi pengujian unit - hanya saja Anda menyebut tes unit Anda sebagai 'spesifikasi'.

Tanggam
sumber
Tidak menyangka akan merasa sedih ketika saya datang ke sini
Roman
3

Akhir-akhir ini nampaknya Mentimun mendapat lebih banyak dukungan di komunitas Rails. Inilah argumen singkat yang saya dengar dari wawancara dengan pimpinan RSpec (dari Ruby on Rails Podcast lama).

Di komunitas lincah (pada saat itu) ada dorongan besar untuk Pengembangan Didorong Uji dengan penekanan pada pengujian pertama untuk membuktikan Anda harus mengubah sesuatu. Ada yang secara philofis salah dengan itu. Intinya, pengujian adalah cara untuk memverifikasi bahwa implementasi Anda sudah benar, jadi bagaimana menurut Anda berbeda tentang desain mengemudi? Pimpinan RSpec menduga bahwa Anda menentukan terlebih dahulu, dan bukankah lebih bagus jika spesifikasi juga memeriksa hasil implementasi Anda?

Penggantian nama sederhana assertuntuk shouldmembantu memfokuskan pikiran dengan cara yang benar untuk menulis spesifikasi, dan berpikir tentang desain. Namun, itu hanya sebagian dari persamaan.

Lebih penting lagi, karena banyak TDD percaya bahwa tes mendokumentasikan desain, sebagian besar dokumentasi buruk. Tes cukup buram untuk non-pengembang yang tidak terbiasa dengan bahasa. Meski begitu, desainnya tidak segera terlihat dari membaca sebagian besar tes.

Jadi sebagai tujuan sekunder, RSpec menemukan cara untuk menghasilkan dokumentasi tertulis dari spesifikasi. Spesifikasi tertulis inilah yang memberikan RSpec keunggulan dibandingkan Test :: Unit sederhana untuk mengarahkan desain suatu aplikasi. Mengapa menulis sesuatu lebih dari sekali ketika Anda dapat mendokumentasikan dan memverifikasi konsistensi desain pada saat yang sama?

Pemahaman saya adalah bahwa Mentimun, yang mendapat manfaat dari datang kemudian dan belajar pelajaran dari RSpec, melakukan pekerjaan yang lebih baik dari tujuan sekunder ini tanpa kehilangan tujuan utama (kemampuan untuk menguji implementasi dari spesifikasi). Mentimun melakukan ini dengan API seperti bahasa Inggris yang dapat dilakukan oleh non-programmer. Mereka mungkin memerlukan bantuan dari programmer untuk mengisi beberapa definisi metode verifikasi baru, tetapi dirancang agar dapat diperluas.

Intinya adalah bahwa RSpec / Mentimun tidak boleh menggantikan pengujian unit sama sekali. Mereka mungkin lebih cocok untuk mendokumentasikan dan memverifikasi desain Anda - tetapi ada beberapa tes implementasi yang masih perlu dilakukan, terutama dengan bug halus yang berasal dari implementasi dan bukan desain aplikasi. Itu memang mengurangi jumlah tes yang harus Anda tulis.

Berin Loritsch
sumber