Ruby on Rails의 Test :: Unit에서 RSpec로 전환하여 얻을 수있는 이점을 실제로 확신하지 못했습니다 (RSpec에 대해 수시로 읽어야 함).
대부분의 Rails 프로젝트에서 사용하고있는 것으로 보이는 RSpec은 무엇입니까?
(일부 코드의 장점을 명확하게 나타내는 일부 코드 예제는 대단히 감사하겠습니다)
Ruby on Rails의 Test :: Unit에서 RSpec로 전환하여 얻을 수있는 이점을 실제로 확신하지 못했습니다 (RSpec에 대해 수시로 읽어야 함).
대부분의 Rails 프로젝트에서 사용하고있는 것으로 보이는 RSpec은 무엇입니까?
(일부 코드의 장점을 명확하게 나타내는 일부 코드 예제는 대단히 감사하겠습니다)
답변:
그것은 주로 맛의 문제이며 소금의 가치가있는 대부분의 테스트 도구는 둘 다 지원합니다. a) 테스트의 출력 및 레이아웃은 테스트중인 객체가 수행해야하는 작업 (코드와 달리)에 초점을 맞추고 b) 'X should Y'라고 말하기 때문에 개인적 선호는 Test :: Unit보다 RSpec입니다. 'X 술어 Y를 주장하는 것'보다 나에게 더 의미가 있습니다.
위의 요점에 대한 컨텍스트를 제공하기 위해 다음은 기능적으로 동등한 두 가지 단위 테스트의 출력 / 소스 코드를 비교 한 것입니다. 하나는 RSpec을 사용하고 다른 하나는 Test :: Unit을 사용했습니다.
테스트중인 코드
class DeadError < StandardError; end
class Dog
def bark
raise DeadError.new "Can't bark when dead" if @dead
"woof"
end
def die
@dead = true
end
end
시험 :: 단위
require 'test/unit'
require 'dog'
class DogTest < Test::Unit::TestCase
def setup
@dog = Dog.new
end
def test_barks
assert_equal "woof", @dog.bark
end
def test_doesnt_bark_when_dead
@dog.die
assert_raises DeadError do
@dog.bark
end
end
end
RSpec
require 'rspec'
require 'dog'
describe Dog do
before(:all) do
@dog = Dog.new
end
context "when alive" do
it "barks" do
@dog.bark.should == "woof"
end
end
context "when dead" do
before do
@dog.die
end
it "raises an error when asked to bark" do
lambda { @dog.bark }.should raise_error(DeadError)
end
end
end
테스트 : : 단위 출력 (완전히 만들 수 있음)
Ξ code/examples → ruby dog_test.rb --verbose
Loaded suite dog_test
Started
test_barks(DogTest): .
test_doesnt_bark_when_dead(DogTest): .
Finished in 0.004937 seconds.
RSpec 출력 (문서 형식 기)
Ξ code/examples → rspec -fd dog_spec.rb
Dog
when alive
barks
when dead
raises an error when asked to bark
Finished in 0.00224 seconds
2 examples, 0 failures
2 tests, 2 assertions, 0 failures, 0 errors
추신 : 나는 Berin (이전 응답자)이 Cucumber (RSpec 프로젝트에서 자랐지 만 독립적 임)와 RSpec의 역할을 혼란스럽게하고 있다고 생각합니다. Cucumber는 BDD 스타일의 자동 수락 테스트를위한 도구 인 반면, RSpec은 단위, 통합 및 기능 수준에서 사용할 수있는 테스트 용 코드 라이브러리입니다. 따라서 RSpec을 사용한다고해서 단위 테스트가 금지되는 것은 아닙니다. 단지 단위 테스트를 '사양'이라고 부릅니다.
최근 Cucumber는 Rails 커뮤니티에서 더 많은 지원을 받고있는 것 같습니다. 다음은 RSpec의 리드와의 인터뷰 (오래된 Ruby on Rails Podcast의)에서 들었던 요점입니다.
애자일 커뮤니티 (당시)에는 테스트 중심 개발에 대한 큰 추진이 있었으며, 먼저 테스트에 중점을 두어 무언가를 변경해야한다는 것을 증명했습니다. 철학적으로 문제가있었습니다. 본질적으로 테스트는 구현이 올바른지 확인하는 방법이므로 운전 설계에 대해 어떻게 다르게 생각하십니까? RSpec의 리드는 먼저 지정 한다고 가정했으며 사양이 구현 결과를 확인하면 좋지 않을까요?
이름을 바꾸는 간단한 assert
로는 should
쓰기 사양에 올바른 방법으로 마음을 집중하고, 디자인에 대해 생각하는 데 도움이됩니다. 그러나 그것은 방정식의 일부일뿐입니다.
더 중요한 것은, 많은 TDD beleivers가 테스트에 디자인이 문서화되었다고 주장했기 때문에 대부분의 문서는 좋지 않았습니다. 테스트는 언어에 익숙하지 않은 비 개발자에게는 상당히 불투명합니다. 그럼에도 불구하고 디자인은 대부분의 테스트를 읽는 것에서 즉시 명백하지 않습니다.
따라서 RSpec은 두 번째 목표로 사양에서 문서를 작성하는 방법을 고안했습니다. RSpec은 응용 프로그램 설계를 주도하는 간단한 Test :: Unit보다 우위를 점하는이 서면 사양입니다. 디자인 일관성을 문서화하고 확인할 수 있는데 왜 무언가를 두 번 이상 작성해야합니까?
나중에 이해하고 RSpec의 교훈을 얻을 수있는 Cucumber는 기본 목표 (사양에서 구현을 테스트 할 수있는 능력)를 잃지 않고이 보조 목표를보다 잘 수행한다는 것을 이해합니다. Cucumber는 프로그래머가 아닌 사람들이 합리적으로 숙달 할 수있는 상당히 영어 같은 API로이 작업을 수행합니다. 새로운 검증 방법에 대한 정의를 작성하려면 프로그래머의 도움이 필요할 수 있지만 확장 가능하도록 설계되었습니다.
결론은 RSpec / Cucumber가 단위 테스트를 완전히 대체해서는 안된다는 것입니다. 그것들은 당신의 디자인을 문서화하고 검증하는데 더 적합 할 것입니다. 그러나 여전히 구현이 필요한 미묘한 버그에 대해 몇 가지 구현 테스트가 필요합니다. 특히 애플리케이션의 디자인이 아닙니다. 그래야 작성해야하는 테스트 수가 줄어 듭니다.