Xamarin.Android の Unit テストをコマンドラインから実行する
はじめに
手順
Android の Instrumentation を利用します
1. TestInstrumentation クラスの実装
Xamarin.Android の Unit Test では、Instrumentation 用に TestSuiteInstrumentation
クラスが提供されおり、これを継承したクラスをテストプロジェクトに追加するだけです。
using System; using Android.App; using Android.OS; using Android.Runtime; using Xamarin.Android.NUnitLite; [Instrumentation(Name = "uitestapp1.uitestapp1.TestInstrumentation")] public class TestInstrumentation : TestSuiteInstrumentation { public TestInstrumentation(IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) { } protected override void AddTests() { AddTest(Assembly.GetExecutingAssembly()); } }
2. テストの実行
- あらかじめ単体テスト用のアプリケーションを端末にインストールしておきます
- adb コマンドでテストを実行します
- 以下の例の "UnitTestApp1.UnitTestApp1" の部分は、自分が作成したテストプロジェクトのパッケージ名に合わせます
- "uitestapp1.uitestapp1.TestInstrumentation" の部分は、
TestSuiteInstrumentation
を継承したクラスに付与したInstrumentation
属性のName
に指定した値に合わせてください
adb shell am instrument -w UnitTestApp1.UnitTestApp1/uitestapp1.uitestapp1.TestInstrumentation
- 結果ファイルの取得
- テストを実行するとテスト結果が表示されます
- テスト結果が出力された xml ファイルのパスも出力されます
- adb pull でテスト結果の XML ファイルを取得します。
adb pull /data/user/0/UnitTestApp1.UnitTestApp1/files/.__override__/TestResults.xml ./TestResults.xml
参考:テスト結果の XML ファイル
テスト結果のファイルは、以下のような XML ファイルになります。(nunit2 の形式)
<?xml version="1.0" encoding="utf-8" standalone="no"?> <!--This file represents the results of running a test suite--> <test-results name="" total="5" errors="0" failures="1" not-run="1" inconclusive="1" ignored="1" skipped="0" invalid="0" date="2017-06-14" time="02:05:01"> <environment nunit-version="1.0.0.0" clr-version="4.0.50524.0" os-version="Unix 3.10.0.0" platform="Unix" cwd="/" machine-name="localhost" user="somebody" user-domain="localhost" /> <culture-info current-culture="ja-JP" current-uiculture="ja-JP" /> <test-suite type="TestSuite" name="" executed="True" result="Failure" success="False" time="0.049" asserts="2"> <failure> <message><![CDATA[One or more child tests had errors]]></message> <stack-trace /> </failure> <results> <test-suite type="Assembly" name="/storage/emulated/0/Android/data/UnitTestApp1.UnitTestApp1/files/.__override__/UnitTestApp1.dll" executed="True" result="Failure" success="False" time="0.046" asserts="2"> <properties> <property name="_PID" value="1200" /> <property name="_APPDOMAIN" value="RootDomain" /> </properties> <failure> <message><![CDATA[One or more child tests had errors]]></message> <stack-trace /> </failure> <results> <test-suite type="TestFixture" name="TestsSample" executed="True" result="Failure" success="False" time="0.035" asserts="2"> <failure> <message><![CDATA[One or more child tests had errors]]></message> <stack-trace /> </failure> <results> <test-case name="Fail" executed="True" result="Failure" success="False" time="0.019" asserts="1"> <failure> <message><![CDATA[ Expected: False But was: True ]]></message> <stack-trace><![CDATA[ at UnitTestApp1.TestsSample.Fail () [0x00001] in <3474bbfc30d04efc9adb490971b61d70>:0 at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <3fd174ff54b146228c505f23cf75ce71>:0 ]]></stack-trace> </failure> </test-case> <test-case name="Ignore" executed="False" result="Ignored"> <properties> <property name="_SKIPREASON" value="another time" /> </properties> <reason> <message><![CDATA[another time]]></message> </reason> </test-case> <test-case name="Inconclusive" executed="True" result="Inconclusive" success="False" time="0.001" asserts="0" /> <test-case name="NewTest" executed="True" result="Success" success="True" time="0" asserts="0" /> <test-case name="Pass" executed="True" result="Success" success="True" time="0.002" asserts="1" /> </results> </test-suite> </results> </test-suite> </results> </test-suite> </test-results>