RSpec vs Test :: Đơn vị trong Rails


15

Tôi chưa bao giờ thực sự bị thuyết phục về những lợi thế mà bạn có được bằng cách chuyển sang RSpec từ Test :: Unit trong Ruby on Rails (mặc dù thỉnh thoảng đọc về RSpec).

Điều gì về RSpec mà hầu hết các dự án Rails dường như đang sử dụng nó?

(một số ví dụ mã cho thấy rõ lợi thế của cái này so với cái kia sẽ được đánh giá cao)


4
Chỉ 1 năm sau và tôi trông có vẻ ghê tởm ở Test :: Đơn vị ... RSpec FTW!
Paweł Gościcki

Gần trùng lặp trên StackOverflow: RSpec vs Test :: UnitRSpec so với Shoulda
sondra.kinsey

Câu trả lời:


13

Đây chủ yếu là vấn đề về hương vị, và hầu hết các công cụ kiểm tra đều có giá trị muối hỗ trợ cả hai. Sở thích cá nhân của tôi là dành cho RSpec so với Test :: Đơn vị vì a) đầu ra và bố cục của các thử nghiệm tập trung vào những gì đối tượng được thử nghiệm phải làm (trái ngược với mã là gì) và b) nói 'X nên Y' có ý nghĩa với tôi hơn là 'khẳng định rằng X vị ngữ Y'.

Để cung cấp cho bạn một số bối cảnh cho các điểm ở trên, đây là một so sánh (khá giả) về mã đầu ra / mã nguồn của hai bài kiểm tra đơn vị tương đương về chức năng, một bài viết sử dụng RSpec và bài kiểm tra khác sử dụng Test :: Unit.

Mã đang thử

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

Kiểm tra :: Đơn vị

 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

Kiểm tra :: Đầu ra đơn vị (đầy đủ như tôi có thể làm cho nó)

Ξ 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.

Đầu ra RSpec (định dạng tài liệu)

Ξ 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

Tái bút: Tôi nghĩ Berin (người trả lời trước) đang hợp nhất vai trò của Cucumber (phát triển từ dự án RSpec nhưng độc lập) và RSpec. Cucumber là một công cụ để kiểm tra chấp nhận tự động theo kiểu BDD, trong khi RSpec là một thư viện mã để kiểm tra có thể, và được sử dụng ở cấp độ đơn vị, tích hợp và chức năng. Do đó, sử dụng RSpec không loại trừ thử nghiệm đơn vị - chỉ là bạn gọi thử nghiệm đơn vị của mình là 'thông số kỹ thuật'.


Tôi không mong đợi sẽ cảm thấy buồn khi tôi đến đây
Roman

3

Gần đây, có vẻ như Cucumber đã nhận được nhiều sự ủng hộ hơn trong cộng đồng Rails. Đây là cuộc tranh luận ngắn gọn mà tôi đã nghe từ một cuộc phỏng vấn với lãnh đạo của RSpec (từ một Ruby cũ trên Rails Podcast).

Trong cộng đồng nhanh nhẹn (vào thời điểm đó) đã có một sự thúc đẩy lớn cho Phát triển hướng thử nghiệm với sự nhấn mạnh vào thử nghiệm trước tiên để chứng minh rằng bạn phải thay đổi điều gì đó. Có một cái gì đó sai về mặt triết học với điều đó. Về bản chất, kiểm tra là một cách để xác minh rằng việc triển khai của bạn là chính xác, vậy bạn nghĩ khác về thiết kế lái xe như thế nào? Khách hàng tiềm năng của RSpec phỏng đoán rằng bạn chỉ định trước, và sẽ không tuyệt nếu thông số kỹ thuật cũng kiểm tra kết quả thực hiện của bạn?

Việc đổi tên đơn giản assertđể shouldgiúp tập trung tâm trí theo cách chính xác để viết thông số kỹ thuật và suy nghĩ về thiết kế. Tuy nhiên, đó chỉ là một phần của phương trình.

Quan trọng hơn, vì nhiều tín đồ TDD đã tuyên bố rằng các thử nghiệm ghi lại thiết kế, nên hầu hết các tài liệu đều kém. Các thử nghiệm khá mờ đối với những người không phải là nhà phát triển không quen thuộc với ngôn ngữ này. Ngay cả sau đó, thiết kế không rõ ràng ngay lập tức từ việc đọc hầu hết các bài kiểm tra.

Vì vậy, như một mục tiêu thứ yếu, RSpec đã nghĩ ra một cách để tạo tài liệu bằng văn bản từ các thông số kỹ thuật. Đây là đặc điểm kỹ thuật bằng văn bản này mang lại cho RSpec một lợi thế so với Test :: Đơn vị để điều khiển thiết kế của một ứng dụng. Tại sao phải viết một cái gì đó nhiều hơn một lần khi bạn có thể ghi lại và xác minh tính nhất quán của thiết kế cùng một lúc?

Hiểu biết của tôi là Cucumber, người có lợi ích đến sau và học bài học từ RSpec, thực hiện tốt hơn mục tiêu thứ yếu này mà không mất mục tiêu chính (khả năng kiểm tra việc thực hiện từ đặc tả). Cucumber thực hiện điều này với API khá giống tiếng Anh mà những người không phải lập trình viên có thể tìm kiếm một cách hợp lý. Họ có thể cần một số trợ giúp từ các lập trình viên để điền vào một số định nghĩa về các phương thức xác minh mới, nhưng nó được thiết kế để có thể mở rộng.

Điểm mấu chốt là RSpec / Cucumber không nên thay thế hoàn toàn thử nghiệm đơn vị. Chúng có thể phù hợp hơn với tài liệu và xác minh thiết kế của bạn - nhưng có một số thử nghiệm triển khai vẫn cần phải thực hiện, đặc biệt là với các lỗi tinh vi xuất phát từ việc triển khai chứ không phải thiết kế của ứng dụng. Nó làm giảm số lượng bài kiểm tra bạn phải viết mặc dù.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.