개요
Rails 에서는 어플리케이션 Test를 위해 기본적으로 Test 모듈(?)들을 제공해준다.
최근에는 Rspec 이 대중적으로 많이 쓰인다고 하지만, Rails 기본 제공 Test 모듈들도 괜찮다는 평이 많은듯 하다(깃헙 눈팅 결과...)
(내가 했던 것들이 테스트가 맞나...)
사실 웹 어플리케이션 테스트는 유저 Behavior를 시뮬레이션하고 서버 로그를 확인하는 정도로 매번 진행했었다.
그렇지만 그렇게 하면서 매번 정확한 테스트가 될지에 대한 걱정들도 없지 않았고 당연히 적절한 방식이 아니라고 생각했다.
Spring 개발환경에서는 무거워서 다방면의 테스트가 쉽지않다는 이야기들도 있었고, 보안상의 DB 접근 등 여러 문제로 쉽지 않았던 것 같다. 어찌됐든, Rails 에서는 테스트 환경을 조금 더 쉽게 제공되고 있기도 하고, TDD(Test Driven Development...)에 익숙해지기 위해 기본적으로 제공되는 테스트 모듈을 사용해보고자 했다.
Rails test를 위한 셋업
먼저 레일즈 프로젝트들을 생성해주고
$ rails new project
scaffold 를 활용해 CRUD 모델을 만들어준다.
저번에도 활용했던 Book 모델이 괜찮은 듯 하여 그대로 사용했다.
$ rails generate scaffold book isbn:bigint name author year:integer price:decimal{7-2} status:boolean genre:integer
1
2
3
4
5
6
7
8
9
10
11
12
|
# db/seeds.rb
100.times do
Book.create(
isbn: Faker::Code.isbn,
name: Faker::Book.title,
author: Faker::Book.author,
year: Faker::Number.between(from:1900, to:2019),
genre: Faker::Number.between(from:1, to:5),
price: Faker::Commerce.price,
status: Faker::Boolean.boolean
)
end
|
cs |
그리고 프로젝트 시작을 위한 기본적인 세팅들도 해줬다.
$ bundle install
$ rake db:migrate
$ rake db:migrate
참고로 위와 같이 Webpacker 에러가 났는데, 저번에도 해결할 때 node 버전의 문제로 해결했던 것 같은데 아니었다.
찾아보니 레일즈 6 버전업이 되면서 기본으로 webpacker 가 포함되면서 아래와 같은 명령어로 해결해줘야 한다.
$ rails webpacker:install
파이썬 커뮤니티에서 해결방법을 찾을 수 있었다는게 조금 아이러니 했지만... 간단한 건데도 많이 삐걱거렸다.
그리고 테스트 환경을 위한 db:migrate나 console 실행들은 아래와 같이 실행할 수 있다.
$ rake db:migrate RAILS_ENV=test
$ rake db:seed RASILS_ENV=test
$ rails c - e test
Rails Test
rails test
Rails는 migrate하는 순간 project/test 디렉토리 내 다양한 part들의 test들을 제공해준다.
먼저 아래는 test 디렉토리 밑에 포함되어 있는 내용들이다.
application_system_test_case.rb controllers/ helpers/ mailers/ system/
channels/ fixtures/ integration/ models/ test_helper.rb
여기서 크게 model, controller, helpers, integration 에 대한 테스트들만 확인해보고자 한다.
Model 테스트
먼저 Model에 대한 테스트를 진행할 때는, 주로 어떠한 데이터 타입에 대해서 유효한지, 또는 어떤 데이터를 넣었을 때 문제가 될 수 있는지 등을 검사할 수 있다.
실제로 사용했던 용도는 String 컬럼 길이에 제한을 두고 이를 넘으면 에러가 제대로 나고 있는지, BigInt 타입에 대한 유효성 검사 등으로 활용했던 것 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
# test/models/book_test.rb
require 'test_helper'
class BookTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
setup do
@book = Book.new(isbn: 123214124,
name: "test book name",
author: "test yoon author",
year: 2020,
genre: 4,
price: 20000,
status: true
)
end
# pass
test "should be valid" do
assert @book.valid?
end
# fail
test "isbn should be integer" do
invalid_int = [13, 2.71828]
invalid_int.each do |i|
@book.isbn = i
assert_not @book.valid?, "#{i.inspect} is invalid."
end
end
# fail
test "name should be present" do
@book.name = 23112313
assert_not @book.valid?
end
# fail
test "year should be integer" do
invalid_year = ["a", 2.71828]
invalid_year.each do |y|
@book.year = y
assert_not @book.valid?, "#{y.inspect} is invalid."
end
end
end
|
cs |
rails test test/models/book_test.rb
위와 같은 테스트를 실행하면 콘솔을 통해 결과를 알 수 있다.
Controller 테스트
Controller가 수행하는 기능들에 대해서 테스트가 가능하며, Scaffold를 활용하면 기본적인 Controller 테스트가 생성되어 있었다.
조금 변경하여 크게 많이 사용되는 아래와 같은 내용의 테스트를 생성하고 실행했다.
- 기본적인 CRUD 동작들에 대한 기능 테스트 수행(get, post, patch, put, delete)
- View에 대한 테스트(특정 elemet 가져오기)
- 라우팅 테스트(url link name을 줬을 때 적절히 타고 갈 수 있는지)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
# test/controller/book_controller.rb
require 'test_helper'
class BooksControllerTest < ActionDispatch::IntegrationTest
setup do
@book = books(:one)
end
# index test
test "should get index" do
get books_path
assert_response :success
end
# views test
test "should display home title" do
get root_path
assert_select "title", "TestProject"
end
# route test
test "should get new" do
get new_book_url
assert_response :success
end
# create test
test "should create book" do
assert_difference('Book.count') do
post books_url, params: { book: { author: @bookŒauthor, genre: @book.genre, isbn: @book.isbn, name: @book.name, price: @book.price, status: @book.status, year: @book.year } }
end
assert_redirected_to book_url(Book.last)
end
# route test
test "should show book" do
get book_url(@book)
assert_response :success
end
# Routing test
test "should get edit" do
get edit_book_url(@book)
assert_response :success
end
# update test
test "should update book" do
patch book_url(@book), params: { book: { author: @book.author, genre: @book.genre, isbn: @book.isbn, name: @book.name, price: @book.price, status: @book.status, year: @book.year } }
assert_redirected_to book_url(@book)
end
# delete test
test "should destroy book" do
assert_difference('Book.count', -1) do
delete book_url(@book)
end
assert_redirected_to books_url
end
end
|
cs |
rails test test/controllers/book_controller.rb
Helpers 테스트
Rails Helpes는 Rails View에서 Reusable 또는 Share를 위해 Built-in으로 제공되는 모듈이다.
조금 더 자세히 알고 싶다면 링크 참조
주로 아래와 같은 방식으로 활용된다.
1
2
3
4
5
6
7
8
9
|
require File.dirname(__FILE__) + '/../spec_helper'
describe FoosHelper do
it "should do something" do
helper.some_helper_method.should == @something
end
end
|
cs |
rails test test/helpers/spec_helper.rb
Integration 테스트
통합테스트 역시 지원해준다.
해당 명령어를 통해 통합테스트를 생성해줄 수 있다.
rails generate integration_test create_flow
예를 들어 아래와 같이 게시글을 작성에 대한 통합테스트를 아래와 같이 할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
|
test "can create an article" do
get "/articles/new"
assert_response :success
post "/articles",
params: { article: { title: "can create", body: "article successfully." } }
assert_response :redirect
follow_redirect!
assert_response :success
assert_select "p", "Title:\n can create"
end
|
cs |
rails test test/integration/create_flow.rb
참고
'Web Programming > Ruby on Rails' 카테고리의 다른 글
Rails Cache 캐시 (0) | 2021.05.09 |
---|---|
Rails API 만들기 (feat. Postman 사용) (2) | 2021.04.04 |
Rails 손쉬운 검색 form ransack (0) | 2021.03.20 |
Rails Database 관리 Gem(rails_db) (0) | 2021.03.20 |
Rake db 명령어(feat. schema:load vs migrate) (5) | 2021.03.14 |