Tối ưu hóa unit test trong Rails

Tram Ho

Unit test là một phần không thể thiếu trong mỗi ứng dụng. Một hệ thống có unit test chạy nhanh và hiệu quả sẽ tiết kiệm được rất nhiều thời gian deploy cho team trong quá trình phát triển. Dưới đây mình xin gợi ý một số cách để có thể tối ưu hóa unit test trong rails:

Sử dụng :create, :build và :build_stubbed một cách hợp lý

create:

Trong trường hợp này một đối tương comment sẽ được tạo ra. Nó và tất cả association sẽ được lưu tại Database.

build:

Trong trường hợp này đối tượng comment sẽ không được lưu vào Database tuy nhiên các association của nó thì có.

build_stubbed:

:build_stubbed sẽ không gọi đến Database. Nó sẽ tạo và gán các thuộc tính cho một đối tượng để làm cho đối tượng hoạt động giống như đối tượng được tạo ra bởi :create. Các association của nó cũng sẽ được tạo bằng :build_stubbed nên hoàn toàn không có tác động nào lên Database.

Khi nào nên dùng :build_stubbed ?

Ta có model:

Factory:

Sử dụng rspec để test cho method full_comment:

Trong hầu hết các trường hợp việc lưu đối tượng vào Database là không cần thiết. Vậy nên khi viết test chúng ta nên hạn chế sử dụng :create mà thay vào đó sử dụng :build:build_stubbed để giảm sự phụ thuộc vào Database. Điều này giúp cho test chạy nhanh và ổn định hơn rất nhiều.

Loại bỏ những association không cần thiết

Ở Ví dụ trên ta có Factory:

Cứ mỗi khi ta tạo một đối tượng comment 1 đối tượng post cũng sẽ được tạo kèm. Việc này sẽ làm ảnh hưởng đến performance của các test case vì không phải lúc nào ta cũng cần sử dụng đến association của nó.

Để tránh việc này ta có thể sửa factory lại thành:

Bây giờ bất cứ khi nào bạn muốn tạo ra một comment kèm post chỉ cần:

Sử dụng before(:all) để loại bỏ let! không cần thiết

Nếu như đoạn test ở ví dụ đầu tiên có nhiều test case hơn:

Lúc này let! sẽ tạo ra một đối tượng comment cho mỗi case (tổng cộng 3 đối tượng) trong khi đó có thể ta chỉ cần sử dụng một. Ta có thể sửa code như sau:

Lúc này tất cả các testcase sẽ sử dụng chung một đối tượng comment.

Tuy nhiên bạn nên thận trọng khi sử dụng before(:all) , trong trường hợp này là việc làm đối tượng comment “global” giữa các test case, các test case có thể thay đổi thuộc tính của đối tượng này dẫn đến làm sai lệch kết quả của các test case khác.

Sử dụng Mock và stub

Nếu bạn không muốn thực thi một phương thức tốn nhiều thời gian (như call API, lấy kết quả từ một module khác có xử lý nặng) bạn có thể fake kết quả trả về bằng stub:

Bạn có thể sử dụng receive_message_chain thay thế receive để stub một chuỗi các methods như sau:

Tham khảo:

https://medium.com/appaloosa-store-engineering/tips-to-improve-speed-of-your-test-suite-8418b485205c

https://relishapp.com/rspec/rspec-core/v/3-6/docs/helper-methods/let-and-let

https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md

https://medium.com/@DmytroVasin/speed-up-your-tests-via-build-stubbed-f1926863b3d7

https://www.netguru.com/blog/9-ways-to-speed-up-your-rspec-tests

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo