tl; dr
Pivotalでは、RubyプロジェクトでRspecを使用して愛しているため、Cedarを作成しました。CedarはOCUnitに置き換わるものや競合するものではありません。RspecがRubyでBDDスタイルのテストを開拓したように、BDDスタイルのテストの可能性をObjective Cにもたらすことを意図していますが、Test :: Unitを排除していません。どちらを選択するかは、主にスタイルの好みの問題です。
場合によっては、OCUnitが機能する方法のいくつかの欠点を克服するためにCedarを設計しました。具体的には、デバッガーをテストで使用したり、コマンドラインやCIビルドでテストを実行したり、テスト結果の有用なテキスト出力を取得したりしたいと考えました。これらのものは多かれ少なかれあなたにとって有用かもしれません。
長い答え
CedarやOCUnitなどの2つのテストフレームワークを決定することは、優先されるスタイルと使いやすさの2つに帰着します。スタイルから始めましょう。それは単に意見と好みの問題だからです。使いやすさはトレードオフのセットになる傾向があります。
スタイルの考慮事項は、使用するテクノロジーや言語を超えています。xUnitスタイルのユニットテストは、BDDスタイルのテストよりもずっと以前から存在していますが、後者は主にRspecにより急速に人気が高まっています。
xUnitスタイルのテストの主な利点は、その単純さと幅広い採用(ユニットテストを作成する開発者の間で)です。コードの記述を検討できるほぼすべての言語で、xUnitスタイルのフレームワークを利用できます。
BDDスタイルのフレームワークは、xUnitスタイルと比較すると、2つの主な違いがある傾向があります。テスト(または仕様)の構造と、アサーションを記述するための構文です。私にとって、構造的な違いが主な差別化要因です。xUnitテストは1次元であり、特定のテストクラスのすべてのテストに対して1つのsetUpメソッドを使用します。ただし、テストするクラスは1次元ではありません。多くの場合、競合する可能性のあるいくつかの異なるコンテキストでアクションをテストする必要があります。たとえば、addItem:メソッドを使用した単純なShoppingCartクラスを考えてみます(この回答のために、Objective C構文を使用します)。このメソッドの動作は、カートが空のときと、カートに他のアイテムが入っているときとで異なる場合があります。ユーザーが割引コードを入力した場合は異なる場合があります。指定の商品ができる場合は異なる場合があります ' t選択した配送方法で配送されます。これらの可能性のある条件が互いに交差する場合、幾何学的に増加する可能性のあるコンテキストの数が生じます。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スタイルのフレームワークの2番目の主な違いであるアサーション(または「マッチャー」)構文は、単に仕様のスタイルをやや良くするだけです。本当に好きな人もいれば、嫌いな人もいます。
それは使いやすさの問題につながります。この場合、各フレームワークには長所と短所があります。
OCUnitはCedarよりはるかに古く、Xcodeに直接統合されています。つまり、新しいテストターゲットを作成するのは簡単で、ほとんどの場合、テストを実行して「そのまま」実行できます。一方、iOSデバイスで実行する場合など、一部のケースでは、OCUnitテストを機能させることがほぼ不可能であることがわかりました。ライブラリを取得して自分でリンクしているため(Xcodeの簡単なタスクではない)、Cedar仕様の設定にはOCUnitテストよりも多くの作業が必要です。私たちはセットアップをより簡単にするために取り組んでおり、どんな提案でも大歓迎です。
OCUnitはビルドの一部としてテストを実行します。つまり、テストを実行するために実行可能ファイルを実行する必要はありません。テストが失敗した場合、ビルドは失敗します。これにより、テストの実行プロセスが1ステップ簡単になり、テスト出力がビルド出力ウィンドウに直接送られるため、見やすくなります。いくつかの理由により、Cedar仕様を実行可能ファイルに組み込み、個別に実行することを選択しました。
- デバッガを使えるようにしたかったのです。他の実行可能ファイルを実行するのと同じようにCedar仕様を実行するので、同じようにデバッガーを使用できます。
- テストで簡単にコンソールロギングが必要でした。OCUnitテストではNSLog()を使用できますが、出力はビルドウィンドウに送られます。ビルドウィンドウを読むには、ビルドステップを展開する必要があります。
- コマンドラインとXcodeの両方で、読みやすいテストレポートが必要でした。OCUnitの結果はXcodeのビルドウィンドウに適切に表示されますが、コマンドラインから(またはCIプロセスの一部として)ビルドすると、テスト出力が多数のその他のビルド出力と混在します。個別のビルドフェーズと実行フェーズにより、Cedarは出力を分離するため、テスト出力を簡単に見つけることができます。デフォルトのCedarテストランナーは、標準スタイルの印刷 "。"をコピーします。合格した各仕様については、「F」は不合格の仕様などです。Cedarにはカスタムレポーターオブジェクトを使用する機能もあります。そのため、少しの労力で好きな方法で結果を出力できます。
OCUnitはObjective Cの公式ユニットテストフレームワークであり、Appleによってサポートされています。Appleは基本的に無制限のリソースを持っているので、彼らが何かをしたいなら、それは成し遂げられるでしょう。そして、結局のところ、これは私たちが取り組んでいるAppleのサンドボックスです。しかし、このコインの裏返しは、Appleが毎日膨大な数のサポートリクエストとバグレポートを受け取るということです。それらはすべてを処理することについては非常に優れていますが、報告した問題をすぐに処理したり、まったく処理したりできない場合があります。CedarはOCUnitよりもはるかに新しく、焼き加減が少ないですが、質問や問題、提案がある場合は、Cedarメーリングリスト(cedar-discuss@googlegroups.com)にメッセージを送信してください。できる限りのお手伝いをします。また、Github(github.com/pivotal/cedar)からコードをフォークして、不足していると思われるものを追加してください。
iOSデバイスでOCUnitテストを実行するのは難しい場合があります。正直なところ、私はしばらくこれを試していなかったので、それは簡単になったかもしれませんが、前回試みたとき、UIKit機能が動作するためのOCUnitテストを取得できませんでした。Cedarを作成するときに、シミュレータとデバイスの両方でUIKitに依存するコードをテストできることを確認しました。
最後に、ユニットテスト用にCedarを作成しました。つまり、UISpecのようなプロジェクトと実際には比較できません。UISpecを使用してみてからかなり時間が経過しましたが、主にiOSデバイスでプログラムによってUIを駆動することに重点を置いていることがわかりました。Appleが(当時)UIAutomationを発表しようとしていたので、Cedarがこれらのタイプの仕様をサポートしないようにすることを明確に決定しました。