在为具有多个UIPickerViews的视图控制器开发Xcode UI测试用例时,我遇到了一些阻止成功的错误,这些错误都与能够在XCUITest中唯一识别选择器有关。
"应该"工作就是在故事板中简单地设置辅助功能标识符或辅助功能标签,如下所示:
但是这对于UIPickerView根本不起作用,尽管我验证了为UIPickerView设置了accessibilityLabel和accessibilityIdentifier属性。是的,我尝试了一个或另一个或两个设置。我甚至尝试以编程方式设置一个或另一个或两者。无论如何,XCUITest案例中的以下行无法找到选择器:
XCUIElement *shippingMethodPicker = app.pickerWheels[@"Shipping method"];
[shippingMethodPicker adjustToPickerWheelValue:@"USPS Media Mail"];
这似乎是一个已知问题,解决方案是使视图控制器也成为UIPickerViewAccessibilityDelegate,并实现 - (NSString *)pickerView:(UIPickerView *)pickerView accessibilityLabelForComponent:(NSInteger)组件委托方法
Apple API Documentation似乎准确描述了为每个pickerWheels组件唯一应用辅助功能标签所需的内容。
但这也有问题,pickerView参数实际上并不是UIPickerView *,正如此stackoverflow链接Unable to get pickerView.tag in -pickerView:accessibilityLabelForComponent: method
中所引用的那样由于委托方法的实现缺陷,您无法确定调用该委托的UIPickerView,以使其对具有多个选择器的视图无效。
由于故事板方法被窃听,并且可访问性委托也被窃听,我找不到从XCUITest测试用例中在视图控制器中唯一标识两个或更多UIPickerView的方法。
任何人都有解决方案吗?
答案 0 :(得分:0)
关注以前的stackoverflow链接评论,我确定了一个适合我的要求的解决方案。
从调试器我们可以确认以前的链接评论观察:
辅助功能委托方法
- (NSString *)pickerView:(UIPickerView *)pickerView accessibilityLabelForComponent:(NSInteger)component;
非常缺陷,没有UIPickerView *,而是私有类UIAccessibilityPickerComponent *。我们可以在调试器中注意到,在这个私有类的私有 _picker 属性中有一个实际的UIPickerView *。
雷达开了。
这是一个内部测试问题,我们不会在App Store的应用程序中发布这个问题。所以我们可以使用私有接口来解决这个问题。我们只会在执行UI测试时编译它。
首先,在Xcode中创建一个新的构建配置,您只能用于测试,从Debug复制。在其中创建一个新的预处理器定义-DXCUITEST,并确保在你的方案中为测试设置这个新的构建配置。
然后按如下方式实现辅助功能委托:
#pragma mark - UIPickerViewAccessibilityDelegate
#ifdef XCUITEST
- (NSString *)pickerView:(UIPickerView *)pickerView accessibilityLabelForComponent:(NSInteger)component {
NSString *label;
UIPickerView *realPickerView;
Ivar picker;
// we are going to work around a bug where the pickerView on this delegate is the wrong class by
// pulling the UIPickerView * that we need from the private property of the UIAccessibilityPickerComponent class
picker = class_getInstanceVariable([NSClassFromString(@"UIAccessibilityPickerComponent") class], "_picker");
// check if the bug still exists and apply workaround only if necessary
if (![pickerView isKindOfClass:[UIPickerView class]])
realPickerView = object_getIvar(pickerView, picker);
else
realPickerView = pickerView;
if (realPickerView == self.shippingMethod)
label = @"Shipping method";
else if (realPickerView == self.someOtherPicker)
label = @"SomeOtherPicker";
return label;
}
#endif
通过这种解决方法,XCUITest测试用例最终按预期执行,成功测试了两个甚至三个UIPickerViews在单个视图上的情况,这些视图都是唯一标识的。请注意,在我的情况下,这些是单轮拣货机,如果你想解决多轮拣货机的问题,那么在代表中实现组件逻辑,这没有错误并按预期工作。
另外,不要忘记将此标题添加到视图控制器类文件的顶部:
#ifdef XCUITEST
#import <objc/runtime.h>
#endif