Xamarin TouchRunner挂起呼叫IOS第三方绑定
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Xamarin TouchRunner挂起呼叫IOS第三方绑定相关的知识,希望对你有一定的参考价值。
我有一个第三方API ios绑定,我试图使用TouchRunner
测试(更像是集成测试)。
一个示例API方法是这样的 -
_client.AuthenticateWithUsername(username, token,
() => { // Success Callback },
() => { // NoConnection Callback },
(obj) => { // Other Error Callback });
调用API时会关闭并在后台执行一些工作然后最终进行上面的回调之一,我想使用类似的东西来控制单元测试的流程
How can I unit test async methods on the UI Thread with Xamarin iOS TouchRunner
不幸的是,当我插入AutoResetEvent
代码时,TouchRunner
只是挂起并且永远不会返回到GUI。
我也试过用TaskCompletionSource
如下 -
public async Task<AuthResponse> AuthenticateUserAsync(string username, string password)
{
TaskCompletionSource<AuthResponse> tcs = new TaskCompletionSource<AuthResponse>();
AuthResponse response = new AuthResponse { Success = false };
LoginResponse loginResponse = await LoginUser(username, password);
_client.AuthenticateWithUsername(username, loginResponse.token,
() =>
{
response.Success = true;
Console.WriteLine("Auth");
tcs.SetResult(response);
},
() => { tcs.SetResult(response); },
obj => { tcs.SetResult(response); },
obj => { tcs.SetResult(response); });
return await tcs.Task;
}
[Test]
public async void AuthenticateUserAsyncTest()
{
var auth = await AuthenticateUserAsync(_username, _password);
Assert.IsTrue(auth.Success);
}
调试器逐步完成,直到返回等待tcs.Task
,但随后导致类似的HUNG跑步者。
我该如何解决悬挂发生的原因?
由于这不起作用,我接着使用这样的代码 -
_client.AuthenticateWithUsername(_username, loginResponse.token,
() =>
{
Assert.Pass("This crashes the runner");
Assert.True(true); // This DOES NOT!
},
() =>
{
// This will crash runner also
Assert.Fail("NoConnection");
},
(InvalidTokenError obj) =>
{
Assert.Fail("InvalidToken" + obj.Description);
},
(ClientError obj) =>
{
Assert.Fail("ClientError" + obj.Description);
});
正如您所看到的,流程最终(可理解),运行测试,运行客户端调用,测试结束方法完成,显示测试成功,然后回调返回并且断言被调用,这使应用程序崩溃,我们假设是因为跑步者已经完成了测试,为什么一个断言工作和其他我不知道的崩溃。
所以,
- 我是以正确的方式接近这个吗?
- 可能会在第三方API中发生导致这些方法挂起的事情吗?我该如何调试呢?
谢谢@Nkosi,这是一个很好的建议,我忘了在原始测试期间添加,当我使用异步任务运行代码而不是无效时,我从TouchRunner立即阻止,甚至没有添加除API调用之外的任何其他代码!我认为这是一个红旗,但使用async void“似乎”允许“标准”异步测试,所以我继续进行,然后在上面的循环中结束。
由于TouchRunner在很长一段时间内没有更新,我花了很多时间在论坛和堆栈中尝试各种建议之后使用XUnit重新创建测试项目。
- https://github.com/xunit/devices.xunit - Xamarin IOS + android的跑步者
- https://xunit.github.io/docs/comparisons - 移植NUnit语法
其他一些有用的链接是 -
- https://xunit.github.io/docs/getting-started-devices.html
- https://gregshackles.com/testing-xamarin-apps-getting-started-with-xunit/
- https://oren.codes/2014/07/10/getting-started-with-xunit-for-xamarin/
结果:我很高兴地说上面的所有代码现在都适用于TaskCompletionSource和AutoResetTask场景
我现在可以安全地测试基于事件的API :)
我只是想确保其他用户都知道这一点。谢谢你的帮助。
一个观察是测试应该是async Task
而不是async void
即
public async Task AuthenticateUserAsyncTest() {
//...code removed for brevity.
}
async void是一个火,忘记所以抛出的任何异常都不会在当前上下文中发生,因此它们不会被捕获。
参考Async/Await - Best Practices in Asynchronous Programming
以上是关于Xamarin TouchRunner挂起呼叫IOS第三方绑定的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Mac 应用程序在与最终用户的文件系统交互时挂起
xamarin forms ios release build 挂起
从 Xamarin PCL 调用 REST API 时程序挂起