2016-12-02 15 views
30

Một đơn vị kiểm tra RSpec điển hình làm cho sử dụng rộng rãi của các khối của Ruby lồng nhau để cấu trúc mã và sử dụng DSL "ma thuật" để có thông số kỹ thuật đọc như báo cáo BDD:Rubocop 25 dòng kích thước khối và RSpec kiểm tra

describe Foo do 
    context "with a bar" do 
    before :each do 
     subject { Foo.new().add_bar } 
    end 

    it "looks like a baz" do 
     expect # etc 

Trong một thông số lý tưởng, mỗi ví dụ có thể tương đối ngắn và chính xác. Tuy nhiên, có vẻ như thường có khối ngoài tăng lên 100 dòng cộng với, vì cấu trúc RSpec hoạt động theo cách này và không lấy nhiều ví dụ cụ thể, mỗi ví dụ có thể có một vài dòng thiết lập cụ thể, để có được các khối describe cùng kích thước hoặc lớn hơn mã cho đối tượng được mô tả.

Việc nâng cấp gần đây của Rubocop đã đưa quy tắc mới vào hoạt động, các khối đó không được dài quá 25 dòng. Tôi không chắc chắn về lý do cho nó, bởi vì nó không được liệt kê trong Ruby style guide. Tôi có thể thấy lý do tại sao nó có thể là một điều tốt, và thêm vào ruleset mặc định. Tuy nhiên, sau khi nâng cấp, thử nghiệm Rubocop của chúng tôi thất bại nhiều lần với những thông điệp như tests/component_spec.rb:151:3: C: Block has too many lines. [68/25]

Với mã cụ metric như Rubocop, tôi thích để có một chính sách "Sử dụng các giá trị mặc định, liên kết để hướng dẫn phong cách, hoàn thành công việc . " Điều này rõ ràng là không thể, hai trong số các công cụ chất lượng dữ liệu cốt lõi của chúng tôi không đồng ý về cách tiếp cận bố cục mã - hoặc ít nhất đó là cách tôi giải thích kết quả, tôi không thấy bất cứ điều gì về bản chất sai với cách chúng tôi đã viết các thông số kỹ thuật.

Để trả lời, chúng tôi chỉ cần đặt quy tắc kích thước khối Rubocop thành ngưỡng cao. Nhưng điều đó khiến tôi tự hỏi - tôi đang thiếu gì? RSpec có sử dụng phương pháp tiếp cận được phân biệt mã ngay bây giờ hay không, và các tuỳ chọn hợp lý nào tôi có phải giảm kích thước khối trong các thử nghiệm RSpec của mình không? Tôi có thể thấy các cách để cơ cấu lại mã để tránh các khối lớn, nhưng chúng không có ngoại lệ xấu xí hacks nhằm hoàn toàn đáp ứng quy tắc của Rubocop, ví dụ: chia nhỏ tất cả các khối thành các chức năng trợ giúp:

def looks_like_a_baz 
    it "looks like a baz" do 
     expect # etc 
    end 
end 

def bar_context 
    context "with a bar" do 
    before :each do 
     subject { Foo.new().add_bar } 
    end 
    looks_like_a_baz 
    end 
end 


describe Foo do 
    bar_context 
    # etc 

. . . Tôi có nghĩa là, đó là do-có thể, nhưng biến loạt các ví dụ spec vào chức năng trợ giúp theo cách này có vẻ là đối diện của phương pháp tiếp cận có thể đọc được khuyến khích bởi thiết kế RSpec.

Tôi có thể làm gì khác ngoài cách tìm cách bỏ qua nó không?


Câu hỏi gần đây nhất mà tôi có thể tìm thấy về chủ đề này ở đây là RSpec & Rubocop/Ruby Style Guide và điều này có thể giải quyết bằng cách chỉnh sửa mẫu thử.

+1

Các [thiết lập mặc định] (https://github.com /bbatsov/rubocop/blob/v0.46.0/config/default.yml#L1156-L1162) loại trừ các tệp trong 'spec /'. – Stefan

+0

@Stefan: Ah, do đó, việc sử dụng 'test /' của chúng tôi đã cho chúng ta thấy điều đó. . . đó là điều tốt để biết. Nó có nghĩa là các tác giả Rubocop thừa nhận một điều gì đó khác với mã RSpec, và chúng ta nên làm như vậy. –

Trả lời

40

Việc nâng cấp gần đây của Rubocop đã đưa quy tắc mới vào hoạt động, các khối đó không được dài quá 25 dòng. Tôi không chắc chắn về lý do cho nó, bởi vì nó không được liệt kê trong hướng dẫn kiểu Ruby.

Nó từng là tất cả cảnh sát được dựa trên Hướng dẫn kiểu Ruby và RuboCop là cách tuân thủ các thực tiễn do cộng đồng đặt ra.

Hướng đã thay đổi kể từ đó và phạm vi của RuboCop đã mở rộng để giúp nhà phát triển đảm bảo tính nhất quán trong cơ sở mã của họ nói chung. Điều này đã dẫn đến hai điều:

  1. Cops (ngay cả những hướng dẫn dựa trên The Ruby Style Guide) bây giờ chủ yếu là cấu hình.
  2. Có cảnh sát cho những thứ không được đề cập trong Hướng dẫn kiểu Ruby, nhưng vẫn hữu ích để thực thi tính nhất quán trong một dự án.

Cảnh sát này nằm trong danh mục thứ hai.

RSpec có sử dụng phương pháp tiếp cận được mã hóa ngay bây giờ và tôi có những lựa chọn hợp lý nào để giảm kích thước khối trong các thử nghiệm RSpec của mình không?

Câu trả lời ngắn gọn là không. DSL vẫn còn mát mẻ. :-)

Cảnh sát này nhằm vào khối lớn theo nghĩa lập trình bắt buộc. Như một hướng dẫn chung, nó không áp dụng cho các DSL, thường được khai báo. Ví dụ: có tệp dài routes.rb trong Rails hoàn toàn lành tính. Nó chỉ là một kết quả tự nhiên của một ứng dụng lớn, chứ không phải là một sự vi phạm phong cách. (Và có rất nhiều bài kiểm tra là hoàn toàn tuyệt vời.)

Bây giờ, RuboCop khá thông minh, nhưng nó không biết DSL là gì và không, vì vậy chúng tôi không thể tự động bỏ qua chúng. Người ta có thể lập luận rằng chúng ta có thể loại trừ các phương thức nhập DSL của các khung công tác phổ biến, như các tuyến Rails và thông số RSpec. Lý do không làm như vậy chủ yếu là:

  1. Sai âm. Bất kỳ lớp nào cũng có thể thực hiện một phương thức, lấy một khối, có cùng tên.
  2. RuboCop là công cụ phân tích Ruby và không thực sự biết về các thư viện bên ngoài. (Không bao gồm các thư mục /spec là phép lịch sự cho đến khi chúng tôi có một hệ thống mở rộng thích hợp, và điều này có thể được xử lý bởi các rubocop-rspec đá quý.)

Ý tôi là, đó là không-thể, nhưng chuyển chùm ví dụ đặc tả vào các hàm trợ giúp theo cách này có vẻ trái ngược với cách tiếp cận có thể đọc được khuyến khích bởi thiết kế RSpec.

Điểm mấu chốt là: RuboCop sẵn sàng giúp chúng tôi viết mã tốt hơn. Nếu thiết kế ứng dụng của chúng tôi là âm thanh khác, và chúng tôi thấy mình làm cho mọi thứ ít có thể đọc được chỉ để làm hài lòng RuboCop, sau đó chúng ta nên lọc, cấu hình, hoặc vô hiệu hóa cảnh sát. :-)

Để trả lời, chúng tôi chỉ cần đặt quy tắc kích thước khối Rubocop thành ngưỡng cao. Nhưng điều đó khiến tôi tự hỏi - tôi đang thiếu gì?

Đây là một công cụ khá thẳng thắn và, như bạn đang gợi ý, có thể bạn sẽ có một số từ khóa phủ định sai vì nó. Có hai loại dương tính giả cho cảnh sát này:

  1. Tệp chứa DSL thuần túy khai báo, ví dụ: Đường ray, thông số RSpec.
  2. Các tệp có DSL kê khai được trộn vào mã chủ yếu bắt buộc, ví dụ: an aasm khai báo máy trạng thái trong mô hình Rails.

Trong trường hợp đầu tiên, giải pháp tốt nhất là loại trừ tệp hoặc thư mục và trong trường hợp thứ hai để sử dụng vô hiệu hóa nội tuyến.

Trong trường hợp của bạn, bạn nên cập nhật của bạn .rubocop.yml với:

Style/BlockLength: 
    Exclude: 
    - 'Rakefile' 
    - '**/*.rake' 
    - 'test/**/*.rb' 

(. Lưu ý rằng bạn cần phải tái lặp những không bao gồm cơ bản từ cấu hình mặc định, vì trong danh sách sẽ được ghi đè)


Tuyên bố từ chối trách nhiệm: Tôi là người đóng góp thường xuyên của RuboCop, nhưng không phải là người duy trì. Tôi dựa trên sự hiểu biết tốt nhất của tôi từ làm việc với cơ sở mã và sau rất nhiều vấn đề.

32

Tôi không thấy Style/Blocklength tùy chọn trong rubocop của default config vì vậy tôi đã đi với giải pháp này trong .rubocop.yml tôi:

Metrics/BlockLength: 
    ExcludedMethods: ['describe', 'context'] 
+0

Tùy thuộc vào tên khối thay vì tên tệp chính xác hơn, vì vậy tôi nghĩ câu trả lời này là tốt hơn. – sekrett

Các vấn đề liên quan