Tăng tốc kiểm tra RSpec trong một ứng dụng Rails lớn


90

Tôi có một ứng dụng Rails với hơn 2.000 ví dụ trong các bài kiểm tra RSpec của mình. Không cần phải nói, đó là một ứng dụng lớn và có rất nhiều thứ để thử nghiệm. Việc chạy các bài kiểm tra này tại thời điểm này là rất kém hiệu quả và vì mất quá nhiều thời gian, chúng tôi gần như đã đến lúc chán nản với việc viết chúng trước khi đẩy một bản dựng mới. Tôi đã thêm --profile vào spec.opts của mình để tìm các ví dụ chạy lâu nhất và có ít nhất 10 trong số đó mất trung bình 10 giây để chạy. Điều đó có bình thường đối với các bạn chuyên gia RSpec không? 10 giây có hoàn toàn quá dài cho một ví dụ không? Tôi nhận ra rằng với 2.000 ví dụ, sẽ mất một khoảng thời gian không hề nhỏ để kiểm tra mọi thứ kỹ lưỡng - nhưng ở thời điểm này thì 4 giờ hơi lố bịch.

Bạn nhìn thấy loại thời gian nào cho các ví dụ hoạt động lâu nhất của mình? Tôi có thể làm gì để khắc phục sự cố thông số kỹ thuật hiện có của mình để tìm ra các điểm nghẽn và giúp đẩy nhanh tiến độ. Mỗi phút sẽ thực sự hữu ích vào thời điểm này.


1
Các bài kiểm tra tích hợp chậm có phải là bài kiểm tra không? Họ đang đánh một db? Nếu vậy, bao lâu thì db được tải lại và bạn có thể chế nhạo db không?
Kaleb Pederson

1
Bạn có thể chỉ chạy một phần của các thông số kỹ thuật có liên quan đến phần bạn đang làm, giống với tính năng tự động của SeattleRB không? Bạn có một máy chủ tích hợp liên tục có thể chạy tất cả các bài kiểm tra không?
Andrew Grimm,

Hãy nhớ rằng tất cả mọi thứ là tương đối. Tôi đã nghe thấy "grrr, bộ thử nghiệm của chúng tôi mất vĩnh viễn" trong cả 20 phút ... và 16-20 giờ. Đó là tất cả trong mắt của người xử lý. 10 giây cho một bài kiểm tra nhất định thường có nghĩa là bài kiểm tra đơn vị đã trở thành bài kiểm tra tích hợp như được đề cập bên dưới.
Michael Durrant

Một gợi ý cho loại vấn đề này: sử dụng perftools.rbcùng với khung kiểm tra của bạn để hiểu những gì đang sử dụng hầu hết thời gian của bạn. Thực hiện 10 cuộc gọi hàng đầu và cố gắng loại bỏ / đọc lướt chúng. Sau đó lặp lại, cho đến khi hạnh phúc.
aledalgrande

Câu trả lời:


118

10 giây là một khoảng thời gian rất dài cho bất kỳ thử nghiệm đơn lẻ nào chạy. Cảm giác ruột của tôi là mục tiêu thông số kỹ thuật của bạn đang chạy cả thử nghiệm đơn vị và tích hợp cùng một lúc. Đây là một điều điển hình mà các dự án rơi vào và ở một số giai đoạn, bạn sẽ cần phải vượt qua món nợ kỹ thuật này nếu bạn muốn sản xuất nhiều hơn, nhanh hơn. Có một số chiến lược có thể giúp bạn làm điều này ... và tôi sẽ giới thiệu một số chiến lược mà tôi đã sử dụng trong quá khứ.

1. Tách Đơn vị khỏi Kiểm tra Tích hợp

Điều đầu tiên tôi sẽ làm là tách đơn vị khỏi các bài kiểm tra tích hợp. Bạn có thể làm điều này bằng cách:

  1. Di chuyển chúng (vào các thư mục riêng biệt trong thư mục cụ thể) - và sửa đổi các mục tiêu rake
  2. Gắn thẻ chúng (rspec cho phép bạn gắn thẻ các bài kiểm tra của mình)

Triết lý đặt ra là bạn muốn các bản dựng thông thường của mình nhanh chóng - nếu không mọi người sẽ không quá vui khi chạy chúng thường xuyên. Vì vậy, hãy quay trở lại lãnh thổ đó. Làm cho các bài kiểm tra thường xuyên của bạn chạy nhanh và sử dụng máy chủ tích hợp liên tục để chạy bản dựng hoàn chỉnh hơn.

Kiểm tra tích hợp là kiểm tra liên quan đến các phụ thuộc bên ngoài (ví dụ: Cơ sở dữ liệu, WebService, Hàng đợi, và một số sẽ tranh luận về Hệ thống tệp). Kiểm tra đơn vị chỉ kiểm tra mục mã cụ thể mà bạn muốn kiểm tra. Nó sẽ chạy nhanh (9000 trong 45 giây là có thể), tức là hầu hết nó sẽ chạy trong bộ nhớ.

2. Chuyển đổi các bài kiểm tra tích hợp thành bài kiểm tra đơn vị

Nếu phần lớn các bài kiểm tra đơn vị của bạn nhỏ hơn bộ kiểm tra tích hợp, thì bạn đã gặp sự cố. Điều này có nghĩa là sự mâu thuẫn sẽ bắt đầu xuất hiện dễ dàng hơn. Vì vậy, từ đây, hãy bắt đầu tạo thêm các bài kiểm tra đơn vị để thay thế các bài kiểm tra tích hợp. Những điều bạn có thể làm để giúp đỡ trong quá trình này là:

  1. Sử dụng khuôn khổ chế nhạo thay vì tài nguyên thực. Rspec có một khuôn khổ mô phỏng có sẵn.
  2. Chạy rcov trên bộ thử nghiệm đơn vị của bạn. Sử dụng điều đó để đánh giá mức độ kỹ lưỡng của bộ thử nghiệm đơn vị của bạn.

Sau khi bạn có (các) bài kiểm tra đơn vị thích hợp để thay thế bài kiểm tra tích hợp - hãy xóa bài kiểm tra tích hợp. Kiểm tra trùng lặp chỉ làm cho việc bảo trì tồi tệ hơn.

3. Không sử dụng đồ đạc

Đồ đạc là xấu xa. Thay vào đó, hãy sử dụng một nhà máy (thợ máy hoặc nhà máy). Các hệ thống này có thể xây dựng các đồ thị dữ liệu thích ứng hơn và quan trọng hơn, chúng có thể xây dựng các đối tượng trong bộ nhớ mà bạn có thể sử dụng, thay vì tải mọi thứ từ nguồn dữ liệu bên ngoài.

4. Thêm kiểm tra để dừng kiểm tra đơn vị trở thành kiểm tra tích hợp

Bây giờ bạn đã có kiểm tra nhanh hơn, đã đến lúc kiểm tra để NGỪNG điều này xảy ra lần nữa.

Có những thư viện mà khỉ vá bản ghi hoạt động để gây ra lỗi khi cố gắng truy cập cơ sở dữ liệu (UnitRecord).

Bạn cũng có thể thử ghép nối và TDD có thể giúp buộc nhóm của bạn viết các bài kiểm tra nhanh hơn vì:

  1. Ai đó đang kiểm tra - vì vậy không ai lười biếng
  2. TDD thích hợp yêu cầu phản hồi nhanh. Các bài kiểm tra chậm chỉ làm cho toàn bộ sự việc trở nên đau đớn.

5. Sử dụng các thư viện khác để khắc phục vấn đề

Ai đó đã đề cập đến spork (tăng tốc thời gian tải cho bộ thử nghiệm trong rails3), hydra /llel_tests - để chạy các bài kiểm tra đơn vị song song (trên nhiều lõi).

Điều này có lẽ nên được sử dụng CUỐI. Vấn đề thực sự của bạn nằm ở bước 1, 2, 3. Giải quyết vấn đề đó và bạn sẽ ở vị trí tốt hơn để xác định cơ sở hạ tầng bổ sung.


Câu trả lời chính xác. Rất đúng là không có công cụ nâng cao nào có thể giúp chạy các bài kiểm tra xấu một cách nhanh chóng. Vì vậy, hãy cố gắng chỉ viết những cái hay.
Yura Omelchuk

5
Tôi không đồng ý về quan điểm thứ ba của bạn rằng bạn không nên sử dụng đồ đạc. Nếu được sử dụng đúng cách, chúng sẽ nhanh hơn các nhà máy vì bạn không phải tạo các đối tượng. Dữ liệu của bạn ở đó, bạn không phải tạo nó với mỗi trường hợp thử nghiệm.
wallerjake

3
Điều này về việc các nhà máy nhanh hơn là một trò đùa, phải không?
Mike Szyndel

Tăng tốc các bài kiểm tra bằng cách tránh có chọn lọc cô gái trong nhà máy - robots.thoughtbot.com/…
geekdev

16

Để có sách dạy nấu ăn tuyệt vời về cách cải thiện hiệu suất của bộ thử nghiệm của bạn, hãy xem bản trình bày Grease Your Suite .

Anh ấy ghi nhận tốc độ tăng gấp 45 lần trong thời gian chạy bộ thử nghiệm bằng cách sử dụng các kỹ thuật như:


Tôi thích các liên kết, nhưng không thích bản trình bày. Thẻ chỉ mục cho ý kiến ​​của ai đó là lời nhắc để người nói điền vào phần nội dung của bài thuyết trình.
Brian Maltzan

Bản trình bày này không còn nữa. fast_context tăng tốc nhiều khối shoulda. Quickerclip (liên kết đó cũng đã chết) rõ ràng là tăng tốc Paperclip. Hydra không được chấp nhận đối với các thử nghiệm song song và Gorgon. bootsnap có các chỉnh sửa hệ thống tệp và hiện được bao gồm trong Rails. Các phiên bản gần đây của Ruby đã cải thiện phân bổ và GC.
đại diện

5

Bạn có thể sử dụng Spork. Nó có hỗ trợ cho 2.3.x,

https://github.com/sporkrb/spork

hoặc ./script/spec_server có thể hoạt động cho 2.x

Ngoài ra, bạn có thể chỉnh sửa cấu hình cơ sở dữ liệu (về cơ bản là tăng tốc các truy vấn cơ sở dữ liệu, v.v.), điều này cũng sẽ tăng hiệu suất cho các bài kiểm tra.


Spork là tuyệt vời. Nó cũng hoạt động trên Rails 3, với một chút hack. Nhưng một điều cần lưu ý với Spork on Rails 3 là nó dường như không nhận các thay đổi trong bộ điều khiển, vì vậy bạn sẽ cần phải khởi động lại nó thường xuyên. Nhưng dù sao thì Spork thực sự rất tuyệt vời, tốc độ cải thiện của các bài kiểm tra là rất đáng kể.
AboutRuby

4
Spork chỉ để tăng tốc khởi động, không phải kiểm tra. Vì vậy, với rất nhiều thông số kỹ thuật, lợi thế là không đáng kể.
Reactormonk

Trái ngược với những nhận xét trên, spork có thể được sử dụng để tăng tốc độ kiểm tra cũng như khởi động theo railscast railscasts.com/episodes/285-spork . Đã cải tiến hàng loạt bộ thử nghiệm rspec của tôi trên một ứng dụng rất lớn. (Giảm từ 192 giây đến 10 giây!)
jamesc

3

10 giây cho mỗi ví dụ có vẻ là một khoảng thời gian rất dài. Tôi chưa bao giờ thấy một thông số kỹ thuật nào mất nhiều hơn một giây và hầu hết mất ít hơn nhiều. Bạn đang kiểm tra kết nối mạng? Cơ sở dữ liệu viết? Hệ thống tập tin ghi?

Sử dụng mocks và khai càng nhiều càng tốt - họ là nhiều nhanh hơn so với viết mã mà lượt truy cập cơ sở dữ liệu. Thật không may, việc chế nhạo và khai man cũng tốn nhiều thời gian hơn để viết (và khó làm đúng hơn). Bạn phải cân bằng giữa thời gian dành cho việc viết bài kiểm tra so với thời gian dành cho việc chạy bài kiểm tra.

Tôi thứ hai nhận xét của Andrew Grimm về việc xem xét một hệ thống CI có thể cho phép bạn song song hóa bộ thử nghiệm của mình. Đối với một thứ có kích thước như vậy, nó có thể là giải pháp khả thi duy nhất.


vâng nếu đó là 10 giây tôi sẽ cấu hình nó và xem nơi cổ chai là
rogerdpack

1
Tôi có một dự án lớn và chạy một bài kiểm tra rspec đơn lẻ mất gần 15-20 giây.
ExiRe

2

Một số người đã đề cập đến Hydra ở trên. Chúng tôi đã sử dụng nó với thành công lớn trong quá khứ. Gần đây tôi đã ghi lại quá trình bắt đầu và chạy hydra: http://logicalfriday.com/2011/05/18/faster-rails-tests-with-hydra/

Tôi đồng ý với quan điểm rằng loại kỹ thuật này không nên được sử dụng để thay thế cho các bài kiểm tra viết có cấu trúc tốt và nhanh theo mặc định.





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.