Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Làm chủ viết test với pattern Ba Giai Đoạn trong Rails

(Đoạn trích ngắn từ Practicing Rails. Đăng ký ở đây nhận chapter 1 miễn phí!)

Bạn làm app mới, Rails generate test cho bạn:

test/models/bug_test.rb
require 'test_helper'
class BugTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end

Bạn uncomment, đặt tên, sẵn sàng viết test, đúng không? Nhưng tiếp theo làm gì? Viết gì trước? Code test trông như nào?

Nếu theo pattern đơn giản, bạn biến những dòng stub thành test case rõ ràng, cấu trúc tốt.

Pattern ba giai đoạn test

Test case nên hoạt động ba giai đoạn:

  1. Thiết lập thứ gì đó ("Arrange")
  2. Thực hiện hành động ("Act")
  3. Kiểm tra điều kỳ vọng có xảy ra không ("Assert")

Ví dụ, test method trên array Ruby. Theo pattern, test trông như:

test "Array#sort will sort an array of numbers" do
  # arrange
  unsorted_array = [7, 4, 2, 3]
  # act
  sorted_array = unsorted_array.sort
  # assert
  assert_equal [2, 3, 4, 7], sorted_array
end

Đơn giản. Nhưng mỗi phần test có chỗ riêng, và từng giai đoạn gần như nói cho bạn cách viết.

Đôi khi không cần Arrange, hoặc Act và Assert gộp. Nhưng vẫn giúp nghĩ ba giai đoạn khi viết test.

Cạm bẫy giai đoạn Assert

Có trick ở Assert: bạn không nên dùng logic giống Act trong Assert. Luôn đi hai đường đến cùng câu trả lời. Nếu không, bạn không nhận ra bug trong code gọi, vì nó chỉ được gọi lại ở Assert.

Ví dụ, làm toán:

test "average returns the average of a set of numbers" do
  # arrange
  numbers = [1, 2, 3, 4]
  # act
  average = numbers.average
  # assert
  # this is bad
  assert_equal [1, 2, 3, 4].average, average
  # this is better
  assert_equal 2.5, average
end

Gọi [1, 2, 3, 4].average lại ở Assert xấu, vì average có thể trả bất cứ gì và assertion vẫn pass.

Ở đây rõ ràng. Nhưng даже khi phức tạp, hãy chắc không chỉ chạy cùng code hai lần. Nếu không, bạn chỉ verify method được gọi, không phải nó chạy như kỳ vọng.

Cách dễ nhất đi đường thứ hai đến câu trả lời là tự tính tay và hardcode. Có thể brittle, nhưng tốt hơn test vỡ mà không hay.

Tại sao ba giai đoạn?

Nếu chia test thành ba giai đoạn, bạn có câu hỏi đơn giản hơn. Thay vì "Viết test này như thế nào?", bạn tập trung từng giai đoạn: "Setup như nào?", "Test cái gì?", "Câu trả lời trông như nào?"

Câu hỏi này vẫn có thể không dễ trả lời, nhưng câu trả lời dễ hơn suy nghĩ cả test cùng lúc. Và may mắn thì bạn chia sẻ giai đoạn giữa test liên quan, làm test sau ít đau khổ hơn.