在 UI 自动化测试中解除警报时未调用 UIAlertView 的委托方法“clickedButtonAtIndex”

Posted

技术标签:

【中文标题】在 UI 自动化测试中解除警报时未调用 UIAlertView 的委托方法“clickedButtonAtIndex”【英文标题】:UIAlertView's delegate's method "clickedButtonAtIndex" not called when alert is dismissed in UI Automation test 【发布时间】:2014-03-20 03:14:42 【问题描述】:

我有一个控制器,当用户单击按钮 [“删除”] 时,它会创建并显示警报。警报视图提示用户确认,或者取消删除,或者完成操作。

当我在我的 iPhone 甚至 iPhone 模拟器中运行代码时,它运行良好 - 如果/当用户单击 UIAlertView 上的“是”按钮时,该项目将被删除。

但是,我正在尝试使用 Instruments 创建 UI 自动化测试。当我运行以下脚本时,警报按预期显示,并且日志显示实际上在模拟过程中点击了“是”按钮。但是,即使解除了警报并点击了“是”按钮,委托方法“clickedButtonAtIndex”方法也不会在我的应用程序的控制器中被调用 - 所以删除永远不会发生。

认为这是一个时间问题,我尝试在点击“是”按钮后添加延迟(除了等待“是”按钮变为无效之外),但没有任何区别。

注意: - 警报视图应保留在内存中,直到控制器被释放,因为警报视图是控制器类的强属性。 - 控制器将自己设置为警报的代表 - 应用程序在不模拟时按预期执行就是证明。

有什么想法吗?

这是脚本:

UIATarget.onAlert = function onAlert(alert) 

    var title = alert.name();

    if (title == expectedAlertMessage) 
    expectedAlertMessage = "";
        return true;  
    
    return false; 


function testDeleteMyFavoriteStore(target, app) 

    var mainWindow = new MainWindow(target, app);             //MainWindow is defined in a separate js file
    var storeNameToDelete = "My Favorite Grocery Store"

    mainWindow.StorePicker().wheels()[0].selectValue(storeNameToDelete);
    mainWindow.EditStoreButton().tap();
    mainWindow.EditStoreButton().waitForInvalid();

    var editStoreWindow = new EditStoreWindow(target, app);   //EditStoreWindow is defined in a separate js file
    expectedAlertMessage = "Delete Store";   
    editStoreWindow.DeleteStoreButton().tap(); 
    editStoreWindow.DeleteStoreButton().waitForInvalid();

    var yesButton = app.alert().buttons()["Yes"];
    yesButton.tap();
    yesButton.waitForInvalid(); 

【问题讨论】:

【参考方案1】:

您可以尝试以下任何一种延迟 -

[1] target.delay(5);   //delay for 5 sec - can use this after your alert appears

[2] Use pushTimeout and popTimeout -

    UIATarget.localTarget().pushTimeout(20);
    window.navigationBar().name()["Welcome"];
    UIATarget.localTarget().popTimeout();

[3] Use isVisible check -

    UIATarget.localTarget().pushTimeout(20);
    window.navigationBar().name()["Welcome"].withValueForKey(1, "isVisible");
    UIATarget.localTarget().popTimeout();


Note : [2] and [3] will make instruments wait up to 20 seconds until the name of the navigation bar has changed to "Welcome."

【讨论】:

我之前尝试过 (1) 和 (2) - 虽然从来没有超过 5 秒的值...我只是重试了 20 秒。我仍然得到相同的结果。 (3) 不断给我一个未定义的错误......还不知道为什么。奇怪的是,我设置的延迟似乎是在 tap() 之前而不是之后暂停应用程序。即,即使我在 tap() 之后插入延迟,模拟器似乎在警报仍然可见时暂停。警报消失后,应用程序会立即返回上一个窗口。【参考方案2】:

您是否分配了警报视图的控制器委托并实现了 UIAlertViewDelegate 协议?

【讨论】:

是的,我都做了。该应用程序在正常运行时正常运行。只有当我使用自动化工具分析应用程序时,才会调用委托。

以上是关于在 UI 自动化测试中解除警报时未调用 UIAlertView 的委托方法“clickedButtonAtIndex”的主要内容,如果未能解决你的问题,请参考以下文章

解除B视图时未调用UITableView函数

WebDriver在解除权限对话框警报后未检测到单击的底部元素

如何在 Firebase 中存储警报文本?

CLLocationManager 警报自行解除

UIAlertController - 如果警报第一次解除,则不执行操作

iOS UI 自动化:在测试执行期间从测试中切换网络设置