tl; dr
Pivotal에서는 Ruby 프로젝트에서 Rspec을 사용하고 좋아하기 때문에 Cedar를 작성했습니다. 삼나무는 OCUnit을 대체하거나 경쟁하기위한 것이 아닙니다. Rspec이 Ruby에서 BDD 스타일 테스트를 개척 한 것처럼 Test :: Unit을 제거하지 않은 것처럼 BDD 스타일 테스트를 Objective C에 제공 할 수 있습니다. 하나 또는 다른 것을 선택하는 것은 스타일 선호의 문제입니다.
어떤 경우에는 OCUnit이 우리를 위해 일하는 방식에서 몇 가지 단점을 극복하도록 Cedar를 설계했습니다. 특히 테스트에서 디버거를 사용하고 명령 줄과 CI 빌드에서 테스트를 실행하고 테스트 결과의 유용한 텍스트 출력을 얻을 수 있기를 원했습니다. 이러한 것들이 당신에게 다소 유용 할 수 있습니다.
긴 대답
Cedar와 OCUnit과 같은 두 가지 테스트 프레임 워크 사이에서 결정하는 것은 선호하는 스타일과 사용 편의성이라는 두 가지로 나뉩니다. 스타일과 함께 시작하겠습니다. 이는 단순히 의견과 선호의 문제이기 때문입니다. 사용 편의성은 일련의 트레이드 오프 인 경향이 있습니다.
스타일 고려 사항은 사용하는 기술이나 언어를 초월합니다. xUnit 스타일 단위 테스트는 BDD 스타일 테스트보다 훨씬 오래 지속되었지만 후자는 Rspec으로 인해 빠르게 인기를 얻었습니다.
xUnit 스타일 테스트의 주요 장점은 단순성과 폭 넓은 채택 (단위 테스트를 작성하는 개발자 중)입니다. 코드 작성을 고려할 수있는 거의 모든 언어에는 xUnit 스타일 프레임 워크가 있습니다.
BDD 스타일 프레임 워크는 xUnit 스타일과 비교할 때 테스트 (또는 스펙)를 구성하는 방법과 어설 션을 작성하는 구문의 두 가지 주요 차이점이 있습니다. 저에게는 구조적 차이가 주요 차별화 요소입니다. xUnit 테스트는 주어진 테스트 클래스의 모든 테스트에 대해 하나의 setUp 메소드가있는 1 차원입니다. 그러나 우리가 테스트하는 클래스는 1 차원이 아닙니다. 우리는 종종 서로 상충되는 여러 상황에서 행동을 테스트해야합니다. 예를 들어 addItem : 메소드가 포함 된 간단한 ShoppingCart 클래스를 생각해보십시오 (이 답변의 목적을 위해 Objective C 구문을 사용하겠습니다). 이 방법의 동작은 카트가 비어있을 때와 카트에 다른 항목이있을 때와 다를 수 있습니다. 사용자가 할인 코드를 입력 한 경우 다를 수 있습니다. 지정된 품목이 가능하면 다를 수 있습니다. 선택한 배송 방법으로 배송되지 않습니다. 이러한 가능한 조건들이 서로 교차 할 때, 당신은 기하학적으로 증가하는 가능한 맥락의 수로 끝납니다. xUnit 스타일 테스트에서는 종종 testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies와 같은 이름을 가진 많은 메소드가 생성됩니다. BDD 스타일 프레임 워크의 구조를 사용하면 이러한 조건을 개별적으로 구성 할 수 있으므로 모든 조건을 쉽게 다루고 개별 조건을 쉽게 찾고 변경하거나 추가 할 수 있습니다. 예를 들어 Cedar 구문을 사용하면 위의 방법은 다음과 같습니다. xUnit 스타일 테스트에서는 종종 testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies와 같은 이름을 가진 많은 메소드가 생성됩니다. BDD 스타일 프레임 워크의 구조를 사용하면 이러한 조건을 개별적으로 구성 할 수 있으므로 모든 조건을 쉽게 다루고 개별 조건을 쉽게 찾고 변경하거나 추가 할 수 있습니다. 예를 들어 Cedar 구문을 사용하면 위의 방법은 다음과 같습니다. xUnit 스타일 테스트에서는 종종 testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies와 같은 이름을 가진 많은 메소드가 생성됩니다. BDD 스타일 프레임 워크의 구조를 사용하면 이러한 조건을 개별적으로 구성 할 수 있으므로 모든 조건을 쉽게 다루고 개별 조건을 쉽게 찾고 변경하거나 추가 할 수 있습니다. 예를 들어 Cedar 구문을 사용하면 위의 방법은 다음과 같습니다.
describe(@"ShoppingCart", ^{
describe(@"addItem:", ^{
describe(@"when the cart is empty", ^{
describe(@"with no discount code", ^{
describe(@"when the shipping method applies to the item", ^{
it(@"should add the item to the cart", ^{
...
});
it(@"should add the full price of the item to the overall price", ^{
...
});
});
describe(@"when the shipping method does not apply to the item", ^{
...
});
});
describe(@"with a discount code", ^{
...
});
});
describe(@"when the cart contains other items, ^{
...
});
});
});
경우에 따라 동일한 어설 션 세트가 포함 된 컨텍스트를 발견 할 수 있으며, 공유 예제 컨텍스트를 사용하여 건조 할 수 있습니다.
BDD 스타일 프레임 워크와 xUnit 스타일 프레임 워크의 두 번째 주요 차이점 인 어설 션 (또는 "매칭 기") 구문은 스펙의 스타일을 약간 더 멋지게 만듭니다. 어떤 사람들은 정말로 그것을 좋아하고 어떤 사람들은 그렇지 않습니다.
그것은 사용하기 쉽다는 문제로 이어진다. 이 경우 각 프레임 워크에는 장단점이 있습니다.
OCUnit은 Cedar보다 훨씬 길 었으며 Xcode에 직접 통합되었습니다. 이것은 새로운 테스트 대상을 만드는 것이 간단하다는 것을 의미하며, 대부분 테스트를 수행하고 "제대로 작동"합니다. 반면에 iOS 기기에서 실행하는 등 일부 경우에는 OCUnit 테스트를 수행하는 것이 거의 불가능하다는 것을 알았습니다. Cedar 사양을 설정하려면 라이브러리를 가져 와서 직접 링크하기 때문에 OCUnit 테스트보다 더 많은 작업이 필요합니다 (Xcode의 사소한 작업은 아닙니다). 우리는 설정을 더 쉽게하기 위해 노력하고 있으며 어떤 제안이라도 환영합니다.
OCUnit은 빌드의 일부로 테스트를 실행합니다. 즉, 테스트를 실행하기 위해 실행 파일을 실행할 필요가 없습니다. 테스트가 실패하면 빌드가 실패합니다. 이를 통해 테스트 실행 프로세스가 한 단계 더 간단 해지고 테스트 출력이 빌드 출력 창으로 직접 이동하여 쉽게 볼 수 있습니다. 우리는 몇 가지 이유로 Cedar 사양을 실행 파일로 빌드하도록 선택했습니다.
- 디버거를 사용할 수 있기를 원했습니다. 다른 실행 파일을 실행하는 것처럼 Cedar 스펙을 실행하므로 동일한 방식으로 디버거를 사용할 수 있습니다.
- 테스트에서 쉬운 콘솔 로깅을 원했습니다. OCUnit 테스트에서 NSLog ()를 사용할 수 있지만 출력을 보려면 빌드 단계를 펼쳐야하는 빌드 창으로 출력이 이동합니다.
- 우리는 명령 줄과 Xcode에서 테스트보고를 쉽게 읽을 수 있기를 원했습니다. OCUnit 결과는 Xcode의 빌드 창에 멋지게 나타나지만 명령 줄에서 빌드하거나 CI 프로세스의 일부로 빌드하면 테스트 출력이 많은 빌드 빌드와 많이 혼합됩니다. 별도의 빌드 및 실행 단계를 통해 Cedar는 출력을 분리하므로 테스트 출력을 쉽게 찾을 수 있습니다. 기본 Cedar 테스트 러너는 표준 스타일의 인쇄 "."를 복사합니다. Cedar는 또한 사용자 지정 리포터 객체를 사용할 수 있으므로 약간의 노력으로 원하는 방식으로 결과를 출력 할 수 있습니다.
OCUnit은 Objective C의 공식 단위 테스트 프레임 워크이며 Apple에서 지원합니다. 애플은 기본적으로 무한한 자원을 가지고 있기 때문에 무언가를 원한다면 끝낼 것이다. 그리고 결국, 이것은 우리가 플레이하고있는 Apple의 샌드 박스입니다. 그러나 그 동전의 단점은 Apple이 매일 bajillion 지원 요청과 버그보고 순서대로 수신한다는 것입니다. 모두 처리하는 데는 상당히 좋지만, 즉시 또는 전혀보고 한 문제를 처리하지 못할 수 있습니다. Cedar는 OCUnit보다 훨씬 새롭고 덜 구워 지지만 질문이나 문제 또는 제안 사항이있는 경우 Cedar 메일 링리스트 (cedar-discuss@googlegroups.com)로 메시지를 보내 주시면 도와 드리겠습니다. 또한 Github (github.com/pivotal/cedar)에서 코드를 포크하고 누락 된 것으로 생각되는 것을 추가하십시오.
iOS 기기에서 OCUnit 테스트를 실행하는 것은 어려울 수 있습니다. 솔직히, 나는 이것을 꽤 오랫동안 시도하지 않았으므로 더 쉬워 졌을 지 모르지만, 마지막으로 시도했을 때 UIKit 기능이 작동하기 위해 OCUnit 테스트를 얻을 수 없었습니다. Cedar를 작성할 때 시뮬레이터와 장치에서 UIKit 종속 코드를 테스트 할 수 있는지 확인했습니다.
마지막으로 단위 테스트를 위해 Cedar를 작성했습니다. 이는 UISpec과 같은 프로젝트와 실제로 비교할 수 없음을 의미합니다. UISpec을 사용해 본 이후 꽤 오래되었지만 iOS 프로그래밍 방식으로 UI를 프로그래밍 방식으로 구동하는 데 중점을 둔 것으로 이해했습니다. 우리는 애플이 UIAutomation을 발표하려고 했으므로 Cedar가 이러한 유형의 사양을 지원하지 않도록 구체적으로 결정했습니다.