Thuật ngữ TDD đã không còn xa lạ với các lập trình viên Việt Nam. Trong bài này Tác giả xin chia sẻ một phần của buổi học về TDD trên lớp Ruby on Rails tại Techmaster.
1. Khái Niệm
TDD là viết tắt của Test Driven Development, cái này chắc ai cũng biết rõ.
TDD còn được hiểu là quá trình Red - Green - Refactoring liên tục trong quá trình phát triển phần mềm
Cụ thể hơn thì TDD có nghĩa là:
- Viết Tests trước - sau đó chạy bộ tests vừa viết --> Đỏ lòm vì viết Test trước, chưa có code.
- Code chạy được --> chạy lại bộ Tests --> Pass hết và màu xanh hết.
- Refactor code cho ngon --> Chạy lại bộ Tests --> Vẫn phải xanh hết.
Điều đó có nghĩa, bạn dành thời gian viết Test, và viết càng cẩn thận, thì về sau bạn Refactor code của mình càng dễ dàng và mạnh dạn :) --> nâng cao chất lượng sản phẩm.
Bạn viết Test tốt --> Về sau nâng cấp hoặc thay đổi chức năng --> bạn vẫn mạnh dạn sửa mà không sợ làm ảnh hưởng các bên liên quan.
- Test --> Hiểu được requirement rõ ràng hơn.
- Test --> giảm thiểu được bugs
- Test --> giảm công sức cho QA, giảm thiểu thời gian test lại sau mỗi lần nâng cấp sản phẩm.
2. Thực Hành với Ruby on Rails
Note: Các bạn nếu chưa từng làm quen với Ruby on Rails nhưng muốn thực hành có thể tham khảo 2 bài đọc khác của Tác giả tại Techmaster.
https://techmaster.vn/posts/12510/nhap-mon-ruby
https://techmaster.vn/posts/7125/ruby-on-rails-mo-dau
- Test Model
Ở bài viết này, tác giả sẽ giới thiệu cách viết Tests sample sử dụng RSpec cho một model rất cơ bản: User với thuộc tính rất cơ bản như user_id, name, smartphone_os. Trong đó user_id là String, không bị trùng lặp, ví dụ 'U001', 'U002', smartphone là thuộc tính hệ điều hành mà điện thoại người đó sử dụng, chỉ có thể là 'IOS' hoặc 'Android', còn name là tên của user, độ dài từ 4 - 30 kí tự, chỉ gồm chữ cái. Tất cả các thuộc tính đều là bắt buộc khác null.
Thêm thư viện rspec-rails
#Gemfile
# ...
group :development, :test do
#...
gem 'rspec-rails', '~> 3.0'
end
Các bạn cần chạy lại bundle install và cấu hình rspec
bundle install & rails generate rspec:install
Sinh tự động model User và file test model user_spec.rb
rails generate model User name:string user_id:string smartphone_os:string
Create và Migrate database
rake db:create db:migrate
Ok, giờ chúng ta đã có thể viết Test cho model User vừa tạo
Các bạn mở file spec/models/user_spec.rb
require 'rails_helper'
RSpec.describe User, type: :model do
## create user and assign to user variable
let(:user) { User.create(user_id: 'U1001', smartphone_os: 'IOS', name: 'Techmaster') }
describe "invalid" do
describe "user_id" do
it "not presence" do
user.userID = ""
expect(user).not_to be_valid
end
it "duplicate" do
duplicate_user = User.new(user_id: 'U1001' smartphone_os: 'Android', name: 'Techmaster 01'
expect(duplicate_user).not_to be_valid
end
end
describe "smartphone_os" do
it "not presence" do
end
it "not in list" do
end
end
describe "name" do
it "not presence" do
end
it "too long" do
end
it "too short" do
end
it "includes number" do
end
end
end
Trong file spec ở trên, Tác giả đã liệt kê ra những trường hợp mà user không được phạm dựa theo requirement của bài toán.
Ngoài type: :model, Rspec còn cung cấp thêm một số type khác như :controller, :request, :view, :routing, :helper.
Phần 1 này chúng ta sẽ chỉ làm quen với :model
Đầu tiên chúng ta tạo đối tượng user cho các test case ở phía dưới
## create user and assign to user variable
let(:user) { User.create(user_id: 'U1001', smartphone_os: 'IOS', name: 'Techmaster') }
Ở đây chúng ta sử dụng cú pháp let của RSpec và cú pháp tạo đối tượng như trong rails console của Ruby on Rails
Một điều mà mình muốn chú ý đó là các viết describe và it. Hơi khó diễn tả nhưng các bạn có đọc sample có thể thấy mình nên chia cụ thể, rõ ràng, và mô tả đúng, vừa đủ điều các bạn test. Mỗi describe sẽ tương ứng với một bộ user use cases và mỗi it sẽ tương ứng với một test case.
Còn về cú pháp "expect(sth).to ... " của RSpec, các bạn có thể tham khảo thêm tại RSpec expectations
Nếu các bạn muốn test user valid, các bạn có thể tham khảo code ở dưới
require 'rails_helper'
RSpec.describe User, type: :model do
## create user and assign to user variable
let(:user) { User.create(user_id: 'U1001', smartphone_os: 'IOS', name: 'Techmaster') }
subject { user }
## user should be valid
it { should be_valid }
## ...
end
Well done, keep going on my next articles :)
Bình luận