Bạn có muốn tìm hiểu cách viết các bài kiểm tra cho các ứng dụng Ruby của mình bằng RSpec không?
Sau đó, bạn đang ở đúng nơi !
Trong hướng dẫn này, tôi sẽ chỉ cho bạn cách thực hiện điều đó.
Nội dung
- 1 Tại sao Bạn nên Viết Kiểm tra?
-
- 1.0.1 Nó xây dựng một mạng lưới an toàn chống lại các lỗi (đặc biệt hữu ích cho việc tái cấu trúc)
- 1.0.2 Nó giúp ghi lại mã của bạn
- 1.0.3 Nó cung cấp cho bạn một vòng phản hồi
- 1.0.4 Nó giúp bạn đảm bảo mã của bạn đang tạo ra kết quả như bạn mong đợi
- 1.0.5 Nó giúp bạn có được một công việc Ruby
-
- 2 Bắt đầu với RSpec
- 3 Ví dụ về kiểm tra RSpec
- 4 Phương pháp RSpec Let
- 5 Cách sử dụng Phương pháp Chủ đề
- 6 Cách chạy mã trước tất cả các thử nghiệm của bạn
- 7 Cách tạo Nhóm con Thử nghiệm
- 8 Cách Tạm thời Vô hiệu hóa Kiểm tra
- 9 Ví dụ về Chạy theo Tên
- 10 Kỳ vọng RSpec &Đối sánh
- 11 Bộ định dạng RSpec
- 12 Cách Tìm các Bài kiểm tra Chậm
- 13 Hướng dẫn về Video RSpec
- 14 Tóm tắt
- 14.1 Có liên quan
Tại sao bạn nên viết bài kiểm tra?
Đây là lý do tại sao:
Nó xây dựng một mạng lưới an toàn chống lại các lỗi (đặc biệt hữu ích cho việc tái cấu trúc)
Nếu bạn không có bộ thử nghiệm thì bạn sẽ không muốn chạm vào mã của mình vì sợ cái gì đó bị hỏng…
… Có các bài kiểm tra làm tăng sự tự tin của bạn!
Nó giúp ghi lại mã của bạn
Các bài kiểm tra của bạn mô tả những gì ứng dụng của bạn sẽ làm.
Nó cung cấp cho bạn một vòng phản hồi
Khi bạn đang thực hiện TDD bạn nhận được một vòng phản hồi điều đó cho bạn biết cần tập trung vào điều gì tiếp theo, hữu ích nếu bạn dễ bị phân tâm.
Nó giúp bạn đảm bảo rằng mã của bạn đang tạo ra kết quả như bạn mong đợi
Điều này rất quan trọng!
Nếu bạn đang viết một số logic phức tạp, thì bạn muốn đảm bảo rằng nó hoạt động với nhiều đầu vào khác nhau &không chỉ với một ví dụ bạn nghĩ ra.
Kiểm tra có thể giúp bạn khám phá các trường hợp góc khuất và ghi lại chúng.
Nó giúp bạn kiếm được một công việc Ruby
Hầu hết các đơn xin việc sẽ đánh giá cao kỹ năng kiểm tra của bạn, giúp bạn tăng cơ hội trúng tuyển.
Bắt đầu với RSpec
Để hiểu cách thức hoạt động của RSpec, hãy xem qua ví dụ từng bước .
Chúng ta sẽ viết một ứng dụng đơn giản để tìm số giai thừa.
Bước đầu tiên :
require 'rspec/autorun' describe Factorial do # ... end
Đây là mã ban đầu để viết RSpec đầu tiên của bạn kiểm tra.
Bạn cần yêu cầu đá quý rspec.
Sau đó, bạn cần tạo một describe
chặn để nhóm tất cả các bài kiểm tra của bạn lại với nhau &cho RSpec biết bạn đang kiểm tra lớp nào.
Tiếp theo là it
khối:
describe Factorial do it "does something" do # ... end end
Đây là tên thử nghiệm, cùng với một cách để nhóm tất cả các thành phần lại với nhau của chính bài kiểm tra.
Các thành phần là:
- Thiết lập
- Bài tập
- Xác minh
Thiết lập là nơi bạn tạo bất kỳ đối tượng nào mà bạn cần tạo.
Đó là giai đoạn chuẩn bị.
Sau đó, bạn gọi phương thức bạn muốn thực hiện để nhận giá trị trả về của nó.
Cuối cùng, bạn xác minh kết quả với mong đợi (RSpec) hoặc khẳng định (Minitest).
Ví dụ kiểm tra RSpec
Bây giờ, nếu chúng ta muốn viết một phương pháp giai thừa, chúng ta phải tìm một số giá trị hợp lệ trực tuyến hoặc bằng cách tính toán thủ công.
Sau đó, chúng tôi sử dụng chúng với các thử nghiệm của mình.
Như thế này :
describe Factorial do it "finds the factorial of 5" do calculator = Factorial.new expect(calculator.factorial_of(5)).to eq(120) end end
Khi bạn chạy mã này (giống như một chương trình Ruby thông thường), bạn sẽ nhận được điều này:
uninitialized constant Factorial (NameError)
Điều này là bình thường vì chúng tôi không có Factorial
lớp học chưa.
Hãy tạo một cái:
class Factorial end
Lỗi tiếp theo sẽ là:
undefined method 'factorial_of'
Tôi sửa lỗi này bằng cách tạo factorial_of
phương pháp:
class Factorial def factorial_of end end
Sau đó chạy lại mã:
wrong number of arguments (given 1, expected 0)
Một lỗi khác! Nhưng bạn biết không?
Đó là một điều tốt 🙂
Lỗi không phải là điều đáng để bạn nản lòng.
Chúng là phản hồi.
Bây giờ:
Thêm một đối số phương thức vào factorial_of
phương pháp:
class Factorial def factorial_of(n) end end
Những gì bạn nhận được bây giờ là một thử nghiệm thất bại :
expected: 120 got: nil
Đây chính xác là nơi bạn muốn đến vào thời điểm này!
Nhiệm vụ tiếp theo là triển khai phương thức:
class Factorial def factorial_of(n) (1..n).inject(:*) end end
Và bạn sẽ nhận được bài kiểm tra vượt qua đầu tiên :
. Finished in 0.00315 seconds (files took 0.09083 seconds to load) 1 example, 0 failures
Đây là cái mà chúng tôi gọi là phát triển theo hướng thử nghiệm (TDD).
Bạn viết các bài kiểm tra trước, sau đó để các bài kiểm tra hướng dẫn bạn những gì bạn cần làm tiếp theo.
Phương thức RSpec Let
Nếu bạn muốn viết nhiều bài kiểm tra & sử dụng lại các đối tượng giống nhau bạn có thể xác định các đối tượng này bằng let
tuyên bố.
Nó trông như thế này:
describe Factorial do let(:calculator) { Factorial.new } it "finds the factorial of 5" do expect(calculator.factorial_of(5)).to eq(120) end end
Bây giờ bạn có thể sử dụng lại calculator
trong tất cả các thử nghiệm của bạn theo cùng một describe
khối.
Một điều bạn nên biết về let
đó có phải là "lười biếng" không.
Ý tôi là gì?
Đối tượng sẽ không được tạo cho đến lần đầu tiên bạn sử dụng nó .
Điều này có thể tạo ra sự khác biệt nếu việc tạo đối tượng này có các tác dụng phụ, như tạo mục nhập cơ sở dữ liệu hoặc ghi vào tệp.
Tốt nhất là bạn nên tránh những tác dụng phụ này, nhưng nếu bạn không thể làm vậy thì hãy sử dụng let!
phương pháp.
Ví dụ :
let!(:user) { User.create("[email protected]") }
let!
phương thức không lười biếng, vì vậy đối tượng sẽ được tạo trước khi chạy bất kỳ thử nghiệm nào.
Cách sử dụng phương pháp chủ đề
Một phiên bản khác của let
là subject
.
Sự khác biệt duy nhất là bạn chỉ có thể có một subject
và nó có nghĩa là một ví dụ của đối tượng chính mà bạn đang thử nghiệm.
RSpec đã tạo một subject
mặc định như thế này:
subject { Factorial.new }
Đây được gọi là "chủ đề ngầm định".
Bạn có thể sử dụng nó như thế này:
describe Factorial do it "finds the factorial of 5" do expect(subject.factorial_of(5)).to eq(120) end end
Bạn có thể đặt tên cho chủ thể của mình:
subject(:calculator) { Factorial.new }
Điều này hoạt động giống như cách sử dụng let
, nhưng nó cho phép sử dụng các kỳ vọng một dòng:
it { should be_empty }
Cách chạy mã trước tất cả các thử nghiệm của bạn
RSpec có các móc thực thi mà bạn có thể sử dụng để chạy thứ gì đó trước và sau mỗi lần kiểm tra hoặc toàn bộ nhóm kiểm tra.
Ví dụ :
describe Shop do before(:all) { Shop.prepare_database } after (:all) { Shop.cleanup_database } end
Nếu bạn muốn chạy mã này cho từng ví dụ (ví dụ =kiểm tra trong RSpec), bạn có thể sử dụng :each
thay vì :all
.
Cách tạo nhóm con thử nghiệm
Nếu bạn đang thử nghiệm các tình huống khác nhau trong ứng dụng của mình thì việc nhóm các thử nghiệm liên quan lại với nhau có thể hữu ích.
Bạn có thể thực hiện việc này bằng cách sử dụng khối ngữ cảnh trong RSpec.
Đây là một ví dụ:
describe Course do context "when user is logged in" do it "displays the course lessons" do end it "displays the course description" do end end context "when user it NOT logged in" do it "redirects to login page" do end it "it shows a message" do end end end
Cách tạm thời vô hiệu hóa kiểm tra
Có thể tắt kiểm tra cho mục đích gỡ lỗi.
Tất cả những gì bạn phải làm là thay đổi it
thành xit
cho các bài kiểm tra bạn muốn vô hiệu hóa.
Ví dụ :
xit "eats lots of bacon" do end
Đừng quên xóa x
khi bạn hoàn thành!
Chạy ví dụ theo tên
Thay vì vô hiệu hóa các bài kiểm tra, bạn có thể lọc các bài kiểm tra bạn muốn chạy bằng -e
cờ.
Ví dụ :
> ruby person.rb -e bacon
Bộ lọc này dựa trên tên bài kiểm tra, vì vậy, ví dụ trên sẽ khớp với bất kỳ bài kiểm tra nào có từ “thịt xông khói” trên đó.
Kỳ vọng RSpec &Đối sánh
Bạn có thể nhớ ví dụ này mà chúng tôi đã và đang sử dụng:
expect(calculator.factorial_of(5)).to eq(120)
Nhưng đây là gì eq(120)
một phần?
Chà, 120 là giá trị mà chúng tôi đang mong đợi…
… Và eq
là những gì chúng tôi gọi là người so khớp.
Đối sánh là cách RSpec so sánh đầu ra của phương pháp của bạn với giá trị mong đợi của bạn .
Trong trường hợp của eq
, RSpec sử dụng ==
toán tử (đọc thêm về toán tử Ruby).
Nhưng có những người so khớp khác bạn có thể sử dụng.
Ví dụ:be_something
đối sánh:
expect(nil).to be_nil
something
là một phương thức vị từ (như empty?
) sẽ được gọi trong kết quả thử nghiệm.
Các đối sánh hữu ích khác:
- bao gồm (đối với mảng và hàm băm)
- start_with
- end_with
- đối sánh (đối với đối sánh biểu thức chính quy)
- be_between
- have_key / have_value (dành cho mã băm)
- be_instance_of
- response_to
- have_attributes (để thử nghiệm các biến phiên bản)
Đối sánh cần chú ý đặc biệt là raise_error
đối sánh.
Lý do là để sử dụng nó, bạn phải gói gọn kỳ vọng của mình trong một khối.
Như thế này :
expect{ :x.count }.to raise_error(NoMethodError)
change
matcher cũng hoạt động như thế này:
expect{ stock.increment }.to change(stock, :value).by(100)
Bộ định dạng RSpec
Đầu ra RSpec mặc định ở định dạng "tiến trình".
Với định dạng này, bạn sẽ thấy các dấu chấm (.
) đại diện cho 1 bài kiểm tra vượt qua mỗi bài, một F
cho một thử nghiệm không thành công (dự kiến và thực tế không khớp) hoặc một E
vì một lỗi.
Nhưng có các tùy chọn định dạng thay thế mà bạn có thể sử dụng.
Đây là danh sách:
- tiến độ
- tài liệu
- json
- html
Bạn có thể kích hoạt chúng bằng cờ -f:
> ruby factorial.rb -f d Person eats lots of healthy food writes many articles Finished in 0.00154 seconds (files took 0.09898 seconds to load) 2 examples, 0 failures
Định dạng tài liệu sử dụng mô tả thử nghiệm của bạn để tạo đầu ra.
Cách tìm các bài kiểm tra chậm
RSpec đi kèm với một tùy chọn rất tiện dụng để lập hồ sơ các bài kiểm tra của bạn .
Chỉ bằng cách chuyển --profile
gắn cờ bạn sẽ có thể xem mỗi bài kiểm tra mất bao lâu để chạy và khắc phục những bài kiểm tra thực sự chậm.
Đây là một ví dụ :
> ruby factorial.rb --profile Factorial finds the factorial of 5 0.00043 seconds
Video hướng dẫn RSpec
Tóm tắt
Bạn đã học cách viết các bài kiểm tra bằng cách sử dụng khuôn khổ kiểm tra RSpec.
Bây giờ đến lượt bạn bắt đầu viết bài kiểm tra của riêng bạn!