What’s a good alternative to setting XCUIDevice.shared.orientation for changing the orientation during XCTests in Xcode 13?
Many of our app’s existing snapshot tests set the device orientation using:
XCUIDevice.shared.orientation = orientation.deviceOrientation
However in Xcode 13, these tests fail due to the following exception being thrown when this method is called:
Failed to set device orientation: Not authorized for performing UI testing actions.
Exception _XCTestCaseInterruptionException * 0x60000082b060 0x000060000082b060
Googling this error led me to find this Flutter issue where they state:
I guess Xcode 13 will limit the use of XCUIDevice to XCUITests.
Our snapshot tests are not XCUITests, though, so what options do we have to force a particular device rotation so that we can snapshot the way the view would look in landscape and portrait?
3
Answers
This solution from @Dmytro on another question works for me, use:
instead of:
and now it works fine.
Note:
.deviceOrientation
refers to our custom extension on UIInterfaceOrientation:I would take issue with the entire premise of your question; you should be doing UI testing for snapshots, not unit testing. UI testing has very powerful support for snapshotting as well as for dropping a lot of other information into the report for later retrieval.
It’s true that a UI test can’t reach into an app’s code and make it behave. But to make the app behave in special ways during testing, a UI test can inject environment variables into the app, where the app itself can configure itself in a special way for testing. See for example Xcode UI Test environment variables not being passed from Scheme on how to do that.
We faced the same problem in our project with snapshot tests. Unfortunately,
UIDevice.current.setValue
didn’t do the trick for us.So, we decided to go with this solution:
name it starting with an ‘A’ so it would be the first in alphabetical order (and thus will be executed before other tests)
override
class setUp()
method with your code for changing device orientation. in our case it is changing it to portrait like so:add a dummy test, so setUp() will be executed:
And that’s it. Of course, it will not work when we trigger only one test and not a whole bundle, but as a workaround it can do. Hopefully, it will be fixed in future Xcode releases.
Here is the full code: