Xamarin Android UnitTest и тестирование инструментов (не формы) - PullRequest
0 голосов
/ 15 января 2019

Недавно я реализовал тесты пользовательского интерфейса в Xamarin Android с использованием Xamarin.UITests в версиях 2.2.4 и NUnit 2.6.4 , как они указаны на официальной странице MS для проверки всего, что связано с пользовательским интерфейсом и соответствующими проверками, скажем, ожидание загрузки изображения, действия кнопок, жестов и т. Д. Это я сделал со всеми Fragments и Activities моего Android проект и в общей сложности мне удалось построить структуру, чтобы успешно выполнить около 300 тестов.

Проблема в том, что теперь Я хочу запускать модульные тесты независимо от пользовательского интерфейса , то есть каждую асинхронную задачу, которая подключается к моему веб-сервису. Мне не удалось создать проект модульного тестирования, в котором я могу создать экземпляр класса из своего проекта и выполнить методы, которые передаются в WS. Я искал много информации для платформы Android, в частности, так что, добавив ссылку на мой проект Android, я могу свободно использовать классы, но я не даю никаких результатов.

Например, после добавления ссылки на мой проект: MyApp.dll , я могу использовать его классы, где у меня есть Fragment с именем ProfileFragment.cs , который содержит асинхронный метод с именем GetProfileAsync().

Я пытаюсь сделать следующее в тесте:

[Test]
public async void GetProfileTest ()
{
    var profileFragment = new ProfileFragment();
    var result = await profileFragment.GetProfileAsync();

    Assert.IsNotNull (result);
}

Однако, используя рамки Xamarin.UITest или NUnit for .Net Framework, я получаю следующую ошибку:

Сообщение: System.IO.FileNotFoundException: не удалось загрузить файл или сборка 'Mono.Android, версия = 0.0.0.0, культура = нейтральная, PublicKeyToken = 84e04ff9cfb79065 'или одна из его зависимостей. система не может найти указанный файл.

Вот два моих вопроса:

- У вас есть идея, как протестировать все асинхронные методы класса в проекте Android в модульном тестировании с использованием NUnit Framework? Мне нужно руководство, как выполнить настройку Проект NUnit, позволяющий создавать экземпляры классов из моего проекта MonoAndroid без получения этого исключения.

- Что я делаю не так?

- Нужно ли выполнять эти тесты на сервере только с использованием NUnit для .Net Framework?

- Должен ли я разделять и создавать методы своих веб-сервисов напрямую в проекте NUnit? Я не знаю, насколько это обслуживаемо, так как у меня есть проверки для режима Release и режима Debug для Мой проект Android, который, в зависимости от того или иного пламени, подключается к другому хосту, частью которого является большое количество методов HTTP GET и POST.

1 Ответ

0 голосов
/ 24 января 2019

Спасибо @ jgoldberger-MSFT и @ SushiHangover за их комментарии.

В итоге у меня было два варианта для достижения моей цели:

Настройка XUnit для Xamarin Android


Вы можете запускать тесты на устройстве с помощью xUnit Framework и xUnit.Runner.Devices . Однако тестовый пакет (все ваши классы тестирования и настройки) должен быть присоединен к текущему проекту Android Xamarin в решении , чтобы ссылка на тот же проект (включая классы, ресурсы и контекст) заявки) могут быть использованы удовлетворительно. В противном случае это приведет к множеству бесконечных ошибок, относящихся к ресурсам Android, потому что вы не можете соединить два приложения.

После установки обеих платформ, упомянутых выше, просто настройте параметры запуска следующим образом:

  • В верхней части класса Activity MainLauncher определите директиву препроцессора : это позволит вам запускать приложение для тестов или с нормальным потоком. Обратите внимание, что в нем есть директива 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 для устройств.

Настройка Xamarin Android Instrumentation


Теперь, если вы хотите запустить инструментальное тестирование в проекте 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 Activity

    [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 не смог найти ваш класс. Например, если мой PackageName равен com.yourpackage.android, а мой класс активности - Login.cs при вашем ActivityAttributes добавьте:

[Activity( ... , Name ="com.yourpackage.android.Login", ...)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...