【问题标题】:How can I unit test async methods on the UI Thread with Xamarin iOS TouchRunner如何使用 Xamarin iOS TouchRunner 在 UI 线程上对异步方法进行单元测试
【发布时间】:2014-09-04 23:48:31
【问题描述】:

我已经成功地在 Xamarin 中使用 TouchRunner (NUnitLite) 进行了以下嵌套异步单元测试:

[Test]
[Timeout (Int32.MaxValue)]
public async void NestedAsyncFail()
{
    await Task.Run(async() =>
    {
        await Task.Delay(1000);
    });

    Assert.AreEqual(1, 0);
}

[Test]
[Timeout (Int32.MaxValue)]
public async void NestedAsyncSuccess()
{
    await Task.Run(async() =>
    {
        await Task.Delay(1000);
    });

    Assert.AreEqual(1, 1);
}

结果:http://i.stack.imgur.com/5oC11.png

但是,如果我想测试一个需要执行一些逻辑但还需要进行一些 UI 更改并因此在主线程上执行的异步方法怎么办?下面是我的尝试,但是有一些问题......

[Test]
[Timeout (Int32.MaxValue)]
public void TestWithUIOperations()
{
    bool result = false;

    NSObject invoker = new NSObject ();
    invoker.InvokeOnMainThread (async () => {
        await SomeController.PerformUIOperationsAsync ();
        result = true;
    });

    Assert.True (result);
}

使用 Timeout 属性时,TouchRunner 可能由于某些线程锁定而冻结。如果没有 Timeout 属性,则断言返回 false - 我相信这是由于 async 方法没有正确等待?

谁能告诉我哪里出错和/或如何完成?

这里解释了我在第一个测试中使用 Timeout 属性: https://bugzilla.xamarin.com/show_bug.cgi?id=15104

【问题讨论】:

  • 您的“成功”异步单元测试可能不正确。断言失败时它的行为如何?
  • 它的行为似乎符合预期,我已更新问题以显示初始测试成功和失败的结果。

标签: ios iphone unit-testing asynchronous xamarin


【解决方案1】:

我在此类情况下使用了AutoResetEvent 来测试我们的异步启动例程:

[Test]
public void CanExecuteAsyncTest()
{
    AutoResetEvent resetEvent = new AutoResetEvent(false);
    WaitHandle[] handles  = new WaitHandle[] { resetEvent};

    bool success = false;

    Thread t = new Thread(() => {
        Thread.Sleep(1000);
        success = true;
        resetEvent.Set();
    });

    t.Start ();

    WaitHandle.WaitAll(handles);

    Assert.Equal(true, success);
}

如果您正在测试 UI 功能,最好使用Calabash 或专门用于测试 UI 流程的相关框架。

【讨论】:

    猜你喜欢
    • 2013-03-15
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2010-11-24
    • 1970-01-01
    相关资源
    最近更新 更多