SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Java/.NETプログラマのためのForce.com開発入門

Force.comプラットフォームでのコーディングサンプル

Java/.NETプログラマのためのForce.com開発入門 第3回

Apexによるコーディング

 何かをコーディングする際、JavaやC#のプログラマであれば、プロダクションコードよりも前にユニットテストのテストコードから書き始めたいと思うかもしれません。Apexにおいても、ある程度のテスト駆動開発ができます。ここで「ある程度」と言っているのは、Apexのコンパイルが、JUnitやNUnitのようなテスティングフレームワークと異なり、ローカル環境で行われないからです。JUnitやNUnitなどに慣れたプログラマにとっては、開発リズムという点で、少し物足りないと感じる場面もあるかもしれません。

サンプルアプリケーションのテストコード

 ここで、前回デプロイし、Force.com IDEのワークスペースに展開したテストコード「PlayManagerTest」を解説していきます。このテストコードは「PlayManager」クラスに対するテストです。

テストクラスの宣言
@isTest
private class PlayManagerTest {

 テストクラスの宣言は、JavaやC#でもおなじみのアノテーションによって行います。「private」なクラスに「@isTest」アノテーションを付けることによって、テストコードとして扱われるようになります。

 「@isTest」アノテーションには「@isTest(seeAllData=true)」といった属性値を付記することができ、「seeAllData」を指定しなかった場合のデフォルトはfalseです。「seeAllData」がtrueの場合、テストを実行した時点で格納されているオブジェクトやカスタム設定のレコードを、テストコード内からクエリーすることができます。falseの場合、テストコード内からクエリーできるのは、発行するクエリーと同じテストメソッドの中で追加されたレコードのみです。なお、テストコード内で追加されたレコードは、テストメソッドの処理の単位で自動的にロールバックされます。

 次はテストメソッドの宣言です。

テストメソッドの宣言
@isTest 
static void testCreateAnswers1() {

 テストメソッドの宣言は、テストクラスと同じく「@isTest」アノテーション(または「testmethod」修飾子)を指定することで行います。「seeAllData」属性の指定も、テストクラスの場合と同様です。一時的に、あるテストメソッドをテストとして実行したくない場合などは、この「@isTest」アノテーションをコメントアウトすると良いでしょう。

コメントアウトされたテストメソッドの宣言
// @isTest 
static void testCreateAnswers1() {

 次にテストメソッドの内容を見ていきます。テストメソッドの序盤では、テストデータとしてのオブジェクトを作成しています。サンプルアプリケーションのオブジェクトである「クイズ」「質問」「プレー」をnew演算子によってメモリ上に生成し、insertによって永続化しています。なお、Apexのリテラル文字列はダブルコーテーションではなく、シングルコーテーションでくくることに注意してください。

Quiz__c quiz = new Quiz__c(Name = 'クイズ1');
insert quiz;

Question__c question = new Question__c(Name = '質問1', Text__c = 'タコの足は何本?', Quiz__c = quiz.Id);
insert question;

Choice__c[] choices = new List<Choice__c>();
choices.add(new Choice__c(Name = '6本', Question__c = question.id));
choices.add(new Choice__c(Name = '8本', Question__c = question.id));
insert choices;

Play__c[] plays = new List<Play__c>();
plays.add(new Play__c(Name = 'プレー1', Quiz__c = quiz.id));

 Apexでは、Force.comのオブジェクトのレコードとApexの「class」によって定義されたクラスのオブジェクト(インスタンス)は似て非なるものです。Force.comのオブジェクトは特別に「SObject」(エスオブジェクト)と呼ばれます。例えばSObjectに対しては、プロパティに割り当てる値をnewの際のカッコの中で指定することができます。次のコードは、上記の「クイズ」オブジェクトのレコードの生成と同じ意味の異なる記述方法を示しています。

異なる記述方法の「クイズ」オブジェクトのレコードの生成
Quiz__c quiz = new Quiz__c();
quiz.Name = 'クイズ1';

 次に、テスト対象であるPlayManagerのインスタンスを生成します。クラスのインスタンスの生成も、SObjectのレコードの生成と同じようにnew演算子によって行います。

PlayManager pm = new PlayManager();

 そして、実際にテストを行いたい対象のメソッドの実行です。「Test.startTest()」と「Test.stopTest()」は、ガバナ制限を測定する範囲の開始と終了を表しています。

Test.startTest();
Answer__c[] answers = pm.createAnswers(plays);
Test.stopTest();

 最後に、「System.assertEquals()」によって、テスト対象のメソッド実行後の値の妥当性を評価します。

System.assertEquals(1, answers.size());
System.assertEquals('質問1の回答', answers[0].Name);
System.assertEquals(question.id, answers[0].Question__c);

Force.comにおけるテストコードの役割

 Force.comにおけるコーディングで最も特徴的と言えるのは、テストコードによるプロダクションコードのカバレッジが平均75%以上でないと、プロダクション環境にデプロイできないということです。これによりプロダクションコードの品質をある程度の水準に保つことができ、マルチテナントのコンピュータリソースを無駄に消費しないことなどに繋がっています。一方で、「とにかくカバレッジだけを確保すれば良い」という考えには、なるべく陥らないように注意しなければなりません。

 Apexにおいても、JavaやC#の場合と同じように、次のようなテストコードの役割があります。

テストコードの主な役割
テストコードの役割 説明
テスト
駆動開発
主にクラスを設計するためのテストコード。クラスを提供する側からではなく、
クラスを利用する立場に立ち、必要最低限の実装から優先的に進めていく手法。
回帰テスト 主に機能の追加や変更の際に、デグレが起こっていないかを確認するためのテストコード。
カバレッジ テストコードを実行した際に、全体のプロダクションコードのうちのどれだけの文が実行されているかの割合。

 テストコードは、それぞれの役割に分けて、別々のものとして実装することができます。もちろん、1つのテストコードですべての役割を果たすことができれば、それに越したことはありません。よく行う方法としては、最初にテスト駆動開発を行い、そのうちのいくつかを整理し、回帰テスト用のテストコードとする方法です。継続的に機能拡張するためには、できるだけテストコードを変更しやすい状態にしておく方が良いからです。この際、カバレッジが下がっていないかを確認しながら、カバーされていないプロダクションコードがある場合は、回帰テスト用のシナリオを追加します。

 Force.comのテストコードには、JavaやC#での開発に比べ、次のような特徴があると言えます。

  • 手作りしなければならないクラスが圧倒的に少ない
  • Apexトリガやワークフローを伴うため、永続化データに対するテストコードが中心になる
  • カバレッジをできるだけ上げるためのテストコードの追加が重要視される

しかしForce.comにおいても、継続的に機能拡張していくことが望ましい点は、他のプラットフォームと変わりがありません。

まとめ

 今回は、前回に引き続きサンプルアプリケーションを利用して、Force.comにおける開発方法を解説しました。テストコードの実装では、これまで培ってきたノウハウが、クラウド上のプラットフォームでも活かせるということをお分かりいただけたと思います。次回は引き続き、プロダクションコードとしてのクラスやトリガのコードを解説します。

参考資料

  1. Developer Force Japan
  2. アピリオ テックブログ
  3. アピリオ CIO ブログ
  4. CloudSpokes

 

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Java/.NETプログラマのためのForce.com開発入門連載記事一覧

もっと読む

この記事の著者

照井 康真(テルイ コウマ)

エンタープライズ領域に破壊的イノベーションをもたらしてきた、クラウドインテグレータの株式会社アピリオ勤務。日本のビジネスアジリティの向上に少しでも貢献すべく、日々奮闘中。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7139 2013/05/29 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー