【问题标题】:How to specify accessibility identifiers for multiple UIPickerViews during XCUITest如何在 XCUITest 期间为多个 UIPickerViews 指定可访问性标识符
【发布时间】:2017-11-01 23:53:23
【问题描述】:

在为具有多个 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 的方法。

谁有解决办法?

【问题讨论】:

    标签: objective-c xcode8 accessibility uipickerview xcode-ui-testing


    【解决方案1】:

    专注于之前的 stackoverflow 链接 cmets,我确定了一个适合我要求的解决方案。

    从调试器中我们可以确认之前的链接评论观察:

    可访问性委托方法,

    - (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 测试用例最终按预期执行,成功测试了单个视图上的两个甚至三个 UIPickerView 的情况,所有这些都唯一标识。请注意,在我的情况下,这些是单轮选择器,如果您想解决多轮选择器的问题,请在委托中实现 component 逻辑,该逻辑没有错误并且按预期工作。

    另外,不要忘记将此标头添加到视图控制器类文件的顶部:

    #ifdef XCUITEST
    #import <objc/runtime.h>
    #endif
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-11
      • 1970-01-01
      • 2020-06-23
      相关资源
      最近更新 更多