Sending app to background and re-launching it from recents in XCTest
Asked Answered
P

3

9

I was looking for a solution to my problem where in I need to send my app to background and re-launch it from the recents after a particular time interval. deactivateAppForDuration() was used to achieve this in Instruments UIAutomation. Does anybody know how to achieve that in XCTest?

Packton answered 17/11, 2016 at 11:11 Comment(3)
You can try to just record the flow, that should give you a pretty good idea of how to achieve this. Recording will not stop after the app is sent to background. Then sleep(n) your test execution or dispatch_after until you get it back to foreground (and stop recording)Genovera
I tried that. After going to background while recording, it accesses App from recent apps using elements of XCUIApplication() (It seems for recorder. system ui become XCUIApplication now). Hence while trying to run that recording, it gives an error. Basically you lose your app's XCUIApplication context if you leave app.Packton
@Packton did the solution I provided below work for you?Borak
B
7

Not positive if this will work, as I haven't tested it yet, but it's worth a shot. If nothing else it should give you a good idea on where to look.

XCUIApplication class provides methods to both terminate and launch your app programmatically: https://developer.apple.com/reference/xctest/xcuiapplication

XCUIDevice class allows you to simulate a button press on the device: https://developer.apple.com/reference/xctest/xcuidevicebutton

You can use these along with UIControl and NSURLSessionTask to suspend your application.

An example of this process using Swift 3 might look something like this (syntax may be slightly different for Swift 2 and below):

func myXCTest() {

    UIControl().sendAction(#selector(NSURLSessionTask.suspend), to: UIApplication.shared(), for: nil)

    Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(launchApp), userInfo: nil, repeats: false)   
}

func launchApp() {
    XCUIApplication().launch()
}

Another way may be simply executing a home button press, and then relaunching the app after a timer passes:

func myXCTest {

    XCUIDevice().press(XCUIDeviceButton.Home)

    Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(launchApp), userInfo: nil, repeats: false)     
}

Neither of these ways may do what you're asking, or work perfectly, but hopefully, it will give you a starting point. You can play with it and find a solution that works for you. Good luck!

Borak answered 27/11, 2016 at 9:34 Comment(4)
I tried it, After the home button was pressed the app was moved to background. But the suspend function was not able to bring the app to foreground again.Packton
So the Timer did not countdown and relaunch the app?Borak
Did this solution work for anyone? I know it has 4 up votes but does it actually work? Based on the comments, its not clear. Thanks.Taunton
Does not work in XCTest cases. These are UI Test objects. The button press did seem to work, but the re-launch did not. It either crashed saying no target application in configuration, or it just didn't launch specifying a bundle identifier.Pines
V
4

If you can use Xcode 8.3 and iOS 10.3 with your current tests, then you might want to try this:

XCUIDevice.shared().press(XCUIDeviceButton.home)
sleep(60)
XCUIDevice.shared().siriService.activate(voiceRecognitionText: "Open {appName}")

Be sure to include @available(iOS 10.3, *) at the top of your test suite file.

This will be relatively equivalent to deactivateAppForDuration(). Just change the sleep() to your desired duration.

Vice answered 27/3, 2017 at 23:7 Comment(0)
H
0

Update for Xcode 14:

        XCUIDevice.shared.press(XCUIDevice.Button.home)
        sleep(30)
        XCUIApplication().launch()
House answered 23/8, 2023 at 17:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.