tafuji's blog

C#, Xamarin, Azure DevOps を中心に書いています。

NUnitLite の TestRunner の自動化設定メモ - Xamarin.Android

Qiita より転載

はじめに

方法

Xamarin.Andorid の場合は、MainActivity クラスの OnCreate メソッド内で、Intent を利用して設定します。 以下に、設定の例を示します。

[Activity(Label = "UnitTestApp1", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : TestSuiteActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        // tests can be inside the main assembly
        AddTest(Assembly.GetExecutingAssembly());
        // or in any reference assemblies
        // AddTest (typeof (Your.Library.TestClass).Assembly);

        // テストを自動実行するかどうかの設定
        Intent.PutExtra("automated", true);
        
        // テスト結果をリモートのサーバーに送信するための設定
        Intent.PutExtra("remote", true);
        Intent.PutExtra("hostName", "192.168.x.xx");
        Intent.PutExtra("hostPort", 11000);

        // Once you called base.OnCreate(), you cannot add more assemblies.
        base.OnCreate(bundle);
    }
}

実行結果

automated の設定を true にして、Emulator 上から実行しました。なお、結果を受信するサーバーは、TCP/IP Builder で代替しています。テストが自動実行されるので、あっけなく Test Runner は終了してしまいますが、左側の TCP/IP Builder 側にテスト結果が送信されていることがわかります。

実行結果

おわりに

CI などでこの自動テストを組み込むには、テスト結果のログを判定して、CI の継続する(中止する)場合があると思いますが、生のログをプログラムで解析して判断ロジックを書くのは少し手間がかかりそうです。 CI などに単体テストを組み込みたい場合は、コマンドラインから単体テストを実行する方法からアプローチしたほうがよさそうです。

参考

送信されたテスト結果を張り付けておきます。

[Runner executing:   Run Everything]
[M4A Version:   ???]
[Board:     unknown]
[Bootloader:    unknown]
[Brand:     Android]
[CpuAbi:    x86 ]
[Device:    donatello]
[Display:   full_donatello-userdebug 6.0 MRA58K eng.vsemu.20160404.101625 test-keys]
[Fingerprint:   Android/full_donatello/donatello:6.0/MRA58K/vsemu04041020:userdebug/test-keys]
[Hardware:  donatello]
[Host:      vsemu-CI7]
[Id:        MRA58K]
[Manufacturer:  VS Emulator]
[Model:     5-inch Marshmallow (6.0.0) XXHDPI Phone]
[Product:   VS Emulator 5-inch Marshmallow (6.0.0) XXHDPI Phone]
[Radio:     unknown]
[Tags:      test-keys]
[Time:      1459790445000]
[Type:      userdebug]
[User:      vsemu]
[VERSION.Codename:  REL]
[VERSION.Incremental:   eng.vsemu.20160404.101625]
[VERSION.Release:   6.0]
[VERSION.Sdk:       23]
[VERSION.SdkInt:    M]
[Device Date/Time:  2017/06/13 13:34:23]



UnitTestApp1.dll

TestsSample
    Fail [FAIL] :   Expected: False
  But was:  True

          at UnitTestApp1.TestsSample.Fail () [0x00001] in <e4c9d5037fd14714b09f994a8c64ff28>: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 
    Ignore [INFO] : another time
    Inconclusive [INFO] : Inconclusive
          at UnitTestApp1.TestsSample.Inconclusive () [0x00001] in <e4c9d5037fd14714b09f994a8c64ff28>: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 
    NewTest Passed
    Pass Passed
TestsSample : 1.463 ms
UnitTestApp1.dll : 1.504 ms
 : 1.567 ms
Tests run: 5, Passed: 2, Failed: 1, Skipped: 1, Inconclusive: 1