How can you change orientation for testing on XCTest for iOS?
Asked Answered
D

4

7

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?

Diomedes answered 25/2, 2016 at 17:27 Comment(0)
G
9

Swift code:

XCUIDevice.shared.orientation = UIDeviceOrientation.portrait;
Gaunt answered 30/12, 2018 at 9:37 Comment(4)
Why read only? Here is documentation developer.apple.com/documentation/xctest/xcuidevice/…Gaunt
orientation is readonly on UIDevice but not on XCUIDevice. This works perfectly.Megalomania
crashes with "Timed out waiting for confirmation of orientation change."Watusi
This no longer works on Xcode 13 unless your test target is an XCUITest target.Arin
G
6

use below solution. Do it in setup method.

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

its working for me.

Ginter answered 25/2, 2016 at 18:16 Comment(3)
This worked for me right in the test function - I did not need to add it to setUp().Erased
error: Cannot assign to property: 'orientation' is a get-only propertyLog
This works for me on iOS 15 SDK / Xcode 13 in regular XCTests. Thanks!Arin
W
2

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)))]
Wally answered 19/7, 2017 at 14:1 Comment(2)
error: Cannot call value of non-function type 'XCUIDevice'Log
using random variables in tests like this is never a good idea. A test case should be deterministic. If you need tests for all orientations, then run them for all orientationsMidnight
G
1

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.
Gymnasiast answered 22/11, 2019 at 21:37 Comment(1)
This answer helped me a lot, thanks! Not sure why it was downvoted. This is the only answer that correctly answers the question, which was for unit tests, not UI tests. One more tip... if you want to make this work on CI and need for "Rotate Device Automatically" to always be set, you can use defaults write com.apple.iphonesimulator RotateWindowWhenSignaledByGuest true.Electrograph

© 2022 - 2024 — McMap. All rights reserved.