Force.com内でテストを定期実行する
はじめに
Force.com開発ではテストコードが絶対必要です。75%以上のコードカバレッジを達成していることが求められています。
今回はテストコードではなく、テスト実行環境について書きたいと思います。
Salesforce がテストコードを書いて実行してね(はぁと) と言うくらいなので、いろいろ方法があります。
もちろん一番簡単なのは「ブラウザから実行」です。メニューから選んで実行するだけ。
しかし、今回はAPIで実行を取り上げたいと思います。
API で実行
Ver23 でベータリリースされたクラス [ApexTestQueueItem] [ApexTestResult] を使ってテスト実行します。
これらのクラスとApex Scheduler を組み合わせることで、定期的にテストができるようになるのです!
それでは、早速コードへ。
global class TestScheduler implements Schedulable{ global void execute(SchedulableContext ctx) { ID jobId= enqueueTestClasses(); System.assert(jobId != null); } public static ID enqueueTestClasses() { ApexClass[] testClasses = [SELECT Id, Name FROM ApexClass WHERE Name LIKE 'T%']; if(testClasses.size() == 0){ return null; } ApexTestQueueItem[] queueItems = new List<ApexTestQueueItem>(); for (ApexClass cls : testClasses) { queueItems.add(new ApexTestQueueItem(ApexClassId=cls.Id)); } insert queueItems; ApexTestQueueItem item = [SELECT ParentJobId FROM ApexTestQueueItem WHERE Id=:queueItems[0].Id LIMIT 1]; return item.parentjobid; } }
Apex Scheduler に登録するクラスは、Schedulable を implements している必要があります。
あとは、テストクラスをかき集めて、ApexTestQueueItem につめて insert しているだけです。
ここでは テストクラスはTで始まるもの です。
なお、ApexTestQueueItem は 「ブラウザから実行」のうちメニュー テスト実行 を行った時と同等のものです。
スケジューラに登録します。
設定->開発->Apexクラス->Apexをスケジュール ボタンから登録できます。
テスト結果確認
テスト結果は「ブラウザから実行」のメニュー テスト実行 で確認できます。
ここではテスト実行して一番最新のものだけを表示するviewerを用意します。
朝四時の定期実行のあとでブラウザからテスト実行した場合は、それが最新になります。
その場合は、メニュー テスト実行の履歴で確認してください。
まずは、Visualforce Page
<apex:page id="page" controller="TestResultsViewer" sidebar="false"> <apex:form id="form"> <apex:outputPanel id="top" layout="block"> </apex:outputPanel> <apex:pageBlock id="middle" mode="detail"> <apex:pageBlockSection columns="1"> <apex:outputText value="{!testTimeStamp} 頃に {!methodCount} メソッド実行されました。"/> <apex:outputText value="成功数は {!passCount} , 失敗数は {!failCount} です。"/> <apex:outputText >詳しい内容を見たい場合は<apex:outputLink value="書き換えてね">Apexテスト実行</apex:outputLink>を確認してください。</apex:outputText> </apex:pageBlockSection> <apex:pageBlockSection columns="2"> <apex:pageBlockTable id="monthList" value="{!testResults}" var="testResult" > <apex:column id="ApexclassName" styleClass="resultCell"> <apex:facet name="header">クラス名</apex:facet> <apex:outputField value="{!testResult.ApexClass.Name}"/> </apex:column> <apex:column id="MethodName" styleClass="resultCell"> <apex:facet name="header">メソッド名</apex:facet> <apex:outputField value="{!testResult.MethodName}"/> </apex:column> <apex:column id="Outcome" styleClass="resultCell" > <apex:facet name="header">成功/失敗</apex:facet> <apex:outputField value="{!testResult.Outcome}"/> </apex:column> <apex:column id="Message" styleClass="resultCell" > <apex:facet name="header">エラーメッセージ</apex:facet> <apex:outputField value="{!testResult.Message}"/> </apex:column> </apex:pageBlockTable> </apex:pageBlockSection> </apex:pageBlock> <apex:outputPanel id="bottom" layout="block"> </apex:outputPanel> </apex:form> </apex:page>
コントローラ
public with sharing class TestResultsViewer { public ApexTestResult[] testResults {get; set;} private Integer passCount = 0; private Integer failCount = 0; public TestResultsViewer(){ Id jobId = [SELECT AsyncApexJobId FROM ApexTestResult order by SystemModstamp desc limit 1].AsyncApexJobId; System.assert(jobId != null); testResults = [SELECT Outcome, ApexClass.Name, MethodName, Message, StackTrace, TestTimestamp FROM ApexTestResult where AsyncApexJobId = :jobId order by ApexClass.Name, MethodName]; System.assert(testResults.size() != 0); for(ApexTestResult result : testResults){ if(result.Outcome == 'Pass'){ passCount++; }else if(result.Outcome == 'Fail'){ failCount++; }else if(result.Outcome == 'CompileFail'){ //今のところなしとしておく } } } public Integer getMethodCount(){ return testResults.size(); } public Datetime getTestTimeStamp(){ return testResults.get(0).TestTimestamp; } public Integer getPassCount(){ return passCount; } public Integer getFailCount(){ return failCount; } }
おわりに
これで継続的にテスト自動実行ができるようになります。しかもForce.com内で完結しています。
この内容前半部は、以下のドキュメントで書かれたものを参考にしています。
Salesforce Developers
ドキュメントはお役立ちです。
この情報で、皆様の手間が一つでも減ればと思います。
合言葉は、
紳士*1がいなくてもCIはできる!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
このエントリーはForce.com Advent Calendarに参加しています。
Force.com Advent Calendar 2011 : ATND
*1:Jenkins のこと。