简体   繁体   中英

How can you change orientation for testing on XCTest for iOS?

I'm trying to test my iOS app using XCTestCase in different orientations. I need a way to programmatic way to change the orientation. I tried doing this in 2 methods, but both didn't change the orientation (orientation remained as UIInterfaceOrientationPortrait).

Attempt 1

[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeLeft;`

Attempt 2

[[UIDevice currentDevice] setValue:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft] forKey:@"orientation"];`

When I read [[UIApplication sharedApplication] statusBarOrientation] Is there another way to change the orientation for testing purposes?

SWIFT代码:

XCUIDevice.shared.orientation = UIDeviceOrientation.portrait;

use below solution. Do it in setup method.

[[UIDevice currentDevice] setValue:
                      [NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
                            forKey:@"orientation"];

its working for me.

This should work, I am changing the orientation randomly because I am running several tests, I hope this is useful

        // Set a random device orientation
    let orient = [UIDeviceOrientation.portrait , UIDeviceOrientation.portraitUpsideDown, UIDeviceOrientation.landscapeLeft, UIDeviceOrientation.landscapeRight]
    XCUIDevice.shared().orientation = orient[Int(arc4random_uniform(UInt32(orient.count)))]

The solution I found ist the following. Hence the rotation is being updated in the hack as mentioned before and additionally the window is forced to re-layout according to the new orientation. Still the simulator stays in portrait mode but the layout within is landscape. That's enough for a unit test on a Bot and if a test fails, you can debug locally with the device correctly rotated by hand.

- (void)forceDeviceOrientationTo:(UIInterfaceOrientation)orientation
{
    [UIDevice.currentDevice setValue:@(orientation) forKey:@"orientation"];

    SEL selector = NSSelectorFromString(@"_updateToInterfaceOrientation:duration:force:");
    NSMethodSignature* methodSignature = [self.projectViewController.view.window methodSignatureForSelector:selector];
    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
    invocation.target = self.projectViewController.view.window;
    invocation.selector = selector;
    [invocation setArgument:&orientation atIndex:2];
    double duration = 0.01;
    [invocation setArgument:&duration atIndex:3];
    BOOL force;
    [invocation setArgument:&force atIndex:4];
    [invocation invoke];

    // give enough time to let the rotation happen
    [NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:duration+0.2]];
}

If you want to run device rotating tests within the XCTest environment, my currently best known strategy is:

  • In Simulator, make sure the Rotate Device Automatically option is set.
  • Create an XCTest Host application and make sure its info.plist Supported interface orientations section is fully removed (you can't do that in your production app as the appStore will reject it.)
  • In the host application delegate implement -application:supportedInterfaceOrientationsForWindow: and return UIInterfaceOrientationMaskAll . This will effectively replace the former info.plist entries.
  • Then within your tests, call the private [UIDevice.currentDevice setValue:@(UIDeviceOrientation…) forKey:@"orientation"]; at need
  • This animates, so wait until all windows have changed their orientation by checking their frames and then continue your testing.
  • To speed up animations in tests, set window.layer.speed = 100 . This makes the animations 100 times faster and hopefully your tests too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM