Edited at

Xamarin.Android の Unit テストをコマンドラインから実行する

More than 1 year has passed since last update.


はじめに


  • Xamarin.Android の Unit Test をコマンドプロンプトから実行し、結果ファイルを取得する方法を記載します


手順

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>