Xamarin Android UnitTest和Instrumentation测试(非表格)

时间:2019-01-14 22:18:32

标签: c# android unit-testing xamarin xamarin.android

最近,我在Xamarin Android using Xamarin.UITests in version 2.2.4NUnit 2.6.4中实现了UI测试,正如它们在official MS page中指出的那样,以测试与用户界面及其各自的验证相关的所有内容,例如,等待要加载的图像,按钮动作,手势等。.这是我对Android项目中的所有FragmentsActivities所做的,总计,我设法构建了可以成功执行约300次操作的结构测试。

问题在于,现在我想独立于UI运行单元测试,也就是说,每个异步任务都连接到我的Web服务。我尚未成功创建一个单元测试项目,在该项目中我可以从我的项目中实例化一个类并执行传递给WS的方法。我特别在Android平台上搜索了很多信息,因此,通过添加我的Android项目的引用,我可以自由地使用这些类,但是我没有给出任何结果。

例如,在添加项目引用: MyApp.dll 后,可以使用其类,其中有一个名为{strong> ProfileFragment.cs < / strong>,其中包含一个名为Fragment的异步方法。

我尝试在测试中执行以下操作:

GetProfileAsync()

但是,使用[Test] public async void GetProfileTest () {     var profileFragment = new ProfileFragment();     var result = await profileFragment.GetProfileAsync();     Assert.IsNotNull (result); } Xamarin.UITest框架时,出现以下错误:

  

消息:System.IO.FileNotFoundException:无法加载文件或   程序集'Mono.Android,版本= 0.0.0.0,文化=中性,   PublicKeyToken = 84e04ff9cfb79065'或其依赖项之一。的   系统找不到指定的文件。

这是我的两个问题:

-您是否知道如何在使用NUnit Framework的单元测试中测试Android项目中类的所有异步方法? 我需要一个指南来进行如何设置一个NUnit项目,这样我就可以从我的MonoAndroid项目中实例化类,而不会收到此异常。

-我在做什么错了?

-仅在.Net Framework中使用NUnit进行后端测试吗?

-是否应该直接在NUnit项目中分离并创建Web服务的方法? 我不知道它的可维护性,因为我已经对Release模式和Debug模式进行了验证。我的Android项目中的一个,该项目取决于一个或另一个或另一个,它连接到不同的主机,其中一部分是大量的HTTP GET和POST方法。

1 个答案:

答案 0 :(得分:0)

感谢 @jgoldberger-MSFT @SushiHangover 的评论。

最后,我有两个选择可以实现自己的目标:

为Xamarin Android设置XUnit


您可以使用xUnit FrameworkxUnit.Runner.Devices在设备上运行测试。但是,测试包(您所有的测试和配置类)必须附加到解决方案中的当前Xamarin Android项目,以便对同一项目的引用(包括类,资源和可以令人满意地使用。否则,由于您无法将两个应用程序放在一起,这将产生许多无穷无尽的错误,涉及到Android资源。

一旦安装了上述两个框架,只需按以下步骤配置启动活动即可:

  • 在MainLauncher Activity类的顶部,定义一个Preprocessor Directive:这将使您能够运行应用程序进行测试或正常运行。请注意,它具有Debug指令,该指令仅在应用程序将在调试中部署时才允许您执行条件。

 //#define TEST // Uncomment this to start UnitTestig

 . . .

 [ /* Your ActivityAttributes */ ]
 public class YourLauncherActivity : Activity {

      protected override void OnCreate(Bundle savedInstanceState)
      {
           base.OnCreate(savedInstanceState);
    #if (DEBUG && TEST)
           // Your TestConfiguration.cs Activity
           Intent iTestConfiguration = new Intent(this, typeof(TestConfiguration));
           StartActivity(iTestConfiguration);
    #endif
    #if !TEST
           // Run your normal Activity here, like Login, etc...
    #endif
            }
        }

    ...

您的测试设置活动应如下所示: TestConfiguration.cs

    [Activity(Label = "TestConfiguration")]
    public class TestConfiguration : Xunit.Runners.UI.RunnerActivity
    {
        //public static Context Context { get; set; }

        protected override void OnCreate(Bundle bundle)
        {
            // tests can be inside the main assembly
            AddTestAssembly(Assembly.GetExecutingAssembly());
            AddExecutionAssembly(typeof(ExtensibilityPointFactory).Assembly);
            // or in any reference assemblies   
            //this.AutoStart = true;
            base.OnCreate(bundle);
            //Context = this;
        }
    }

然后使用xUnit Framework定义项目中的测试,例如: MyTests.cs

public class MyTests
    {

        public MyTests()
        {
            // Before each test
        }


        [Fact]
        public void FailingTest()
        {
            Assert.True(false);
        }
    }

现在,您可以在已创建的“ xUnit Runner for Devices”活动上运行测试。

设置Xamarin Android工具


现在,如果要在Xamarin Android项目中运行检测测试,则应执行以下操作:

首先,逐步执行以下教程:

完成后,在测试的配置类中为您的TestSuiteInstrumentation添加静态引用,例如: TestInstrumentation.cs

. . .
        public static TestSuiteInstrumentation CurrentInstrumentation { get; set; }

        public TestInstrumentation(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer)
        {
            CurrentInstrumentation = this;
        }
. . .

现在,如果要配置测试,以便隐式运行Activity并使用其视图,属性等,则可以执行以下操作: Login.cs 的示例活动

    [TestFixture]
    public class LoginTests
    {
        private TestSuiteInstrumentation instrument = TestInstrumentation.CurrentInstrumentation;
        private Activity CurrentActivity;

        [SetUp]
        public void SetUp()
        {
            Instrumentation.ActivityMonitor monitor = instrument.AddMonitor($"{instrument.TargetContext.PackageName}." + nameof(Login), null, false);

            Intent intent = new Intent();
            intent.AddFlags(ActivityFlags.NewTask);
            intent.SetClassName(instrument.TargetContext, $"{instrument.TargetContext.PackageName}." + nameof(Login));

            Task.Run(() => instrument.StartActivitySync(intent)).GetAwaiter();

            Activity currentActivity = instrument.WaitForMonitor(monitor);

        }

        [Test]
        public void LoginTest()
        {
            // Verify your activity is not null 
            Assert.NotNull(CurrentActivity);

            // Convert CurrentActivity to your Activity
            Login login = CurrentActivity as Login;


            // Verify your views are not null, finding views in your Activity
            Assert.NotNull(login);
            Assert.NotNull(login.FindViewById<EditText>(Resource.Id.etLoginUsername));
            Assert.NotNull(login.FindViewById<EditText>(Resource.Id.etLoginPassword));


            instrument.RunOnMainSync(() => {

                // Here you can run your UI methods or properties for Views, example
                login.FindViewById<EditText>(Resource.Id.etLoginUsername).Text = "hello";
                login.FindViewById<EditText>(Resource.Id.etLoginPassword).Text = "world";
            });

            // Here will be your assertions
        }
    } 

现在使用ADB运行测试。请按照以下步骤操作:

  • 以调试或发布模式部署应用程序。然后停止它。
  • 找到仪器测试,使用以下命令:

    adb shell pm list instrumentation

  • 复制要执行的测试的全名,然后执行以下命令:

    adb shell am instrument -w /*paste the full name of your instrumentation test*/

重要提示:您的活动需要在ActivityAttribute中具有定义的名称,以防止 classes.dex 文件找到您的课程。例如,如果在您的com.yourpackage.android添加时,我的PackageName是ActivityAttributes,而我的活动类是 Login.cs ,则:

[Activity( ... , Name ="com.yourpackage.android.Login", ...)]