Search code examples
objective-cxcode8uipickerviewxcode-ui-testing

XCUITest using adjustToPickerWheelValue: && viewForRow: delegate results in assertion


I ran into a situation where I could not get an XCUITest for a view controller containing a UIPickerView to work without an assertion being generated. The problem causing the assertion is clearly from a spurious "1 of n" being appended to each of the picker values by the accessibility functionality used by XCUITest.

Something as simple as this one line would assert during the test

[app.pickers.pickerWheels.element adjustToPickerWheelValue:@"ANYVALUE"];

This turns out to be a known bug with Xcode, and there is an open radar Cannot use UI Testing to adjust pickerView which uses a view-based delegate

This was my problem exactly as I use the viewForRow: delegate in order to use attributed strings in the picker values. The alternative, using the titleForRow: delegate, does NOT exhibit the problem.

I have tried to work around this by manually setting accessibility information, but to no avail.

And I cannot consider using the titleForRow: delegate, due to my clients requirements for the attributed text.

Yet the dilemma, to also deliver complete XCUITests for all views as another client requirement.

What viable workarounds are there?


Solution

  • This is a known bug in Xcode, and it has been opened for quite some time now, going back to at least this 2015 Apple Developer Forum Post

    No fix coming obviously.

    My solution to meet all client requirements was to create an additional build configuration called "Testing", which was duplicated from "Debug", so that I could define a new preprocessor macro XCUITEST. Then editing the scheme under Test to use this new build configuration, instead of either DEBUG or RELEASE.

    With this change I could incorporate the delegate that works for XC testing and yet keep the one that meets the client app requirements like so:

    #ifndef XCUITEST  // for release or debug we use this method as we want attributed text strings
    - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
    
    // blah blah
    
    }
    #endif
    
    #ifdef XCUITEST  // for testing we have to use this method so XCUITests will work with adjustToPickerWheelValue:
    - (UIView *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    
    // blah blah
    
    }
    #endif