How to speed up UI test cases in Xcode?

前端 未结 7 1626
自闭症患者
自闭症患者 2020-12-13 14:29

Since Xcode 7 we have a nice API for UI testing. Mostly I\'m satisfied with it. The only concern is related to the speed.

In the beginning an ordina

相关标签:
7条回答
  • 2020-12-13 15:11

    Add it in didFinishLaunch

    [UIApplication sharedApplication].keyWindow.layer.speed = 2;
    

    The default value is 1, make it 2 to double its speed.

    0 讨论(0)
  • 2020-12-13 15:15

    Another possibility is to disable animations at all:

    [UIView setAnimationsEnabled:NO];
    

    Swift 3:

    UIView.setAnimationsEnabled(false)
    
    0 讨论(0)
  • 2020-12-13 15:15

    Run them in parallel.

    If you have only 1 build machine, you can use Bluepill: https://github.com/linkedin/bluepill

    If you have multiple machines, you can use Emcee: https://github.com/avito-tech/Emcee (it also works for a single machine setup)

    We have 50 hours of UI tests, and Emcee allows us to run them in 1 hour. There are several tricks to make UI tests faster, but it is pointless if you are not running them in parallel. E.g. you can't make your 25 seconds tests run in 0.5 second.


    Tricks:

    1. Run XCUIApplication without reinstalling it:
    XCUIApplication(
        privateWithPath: nil,
        bundleID: "your.bundle.id"
    )
    

    Note: you should launch app with XCUIApplication().launch() at least once per launching XCUI test runner to install the app. This requires usage of private API.

    1. You can move something to background thread. E.g.
    let someDataFromApi = getSomeData() // start request asynchronously and immediately return
    launchApp() // this can be few seconds
    useInTest(someDataFromApi) // access to data will wait request to finish
    

    You can make the code look like there is no asynchronous things, it would be easier for QA. We want to implement this, but we didn't, so it is just an idea.

    1. Switch to EarlGrey and make tests that lasts few seconds (but they will not be black box).

    2. Open screens via deep links if you have deep links.

    3. Use a lot of private API and other hacks. E.g.: instead of going via UI to Settings app and then reset privacy settings you can call some private API.

    4. Never use long sleeps. Use polling.

    5. Speed up animations. Do not disable them!

    6. Pass some flags from UI tests to app to skip initial alerts/tutorials/popups. Can save a lot of time. Be sure to have at least 1 test that checks that those alerts work.

    0 讨论(0)
  • 2020-12-13 15:22

    Try setting this property when your UI tests run:

    UIApplication.shared.keyWindow?.layer.speed = 100
    

    Here's how I set it:

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
        if ProcessInfo.processInfo.arguments.contains("UITests") {
            UIApplication.shared.keyWindow?.layer.speed = 100
        }
    }
    

    And in my UI tests:

    class MyAppUITests: XCTestCase {
    
        // MARK: - SetUp / TearDown
    
        override func setUp() {
            super.setUp()
    
            let app = XCUIApplication()
            app.launchArguments = ["UITests"]
            app.launch()
        }
    }
    

    There's a few more handy tips in this blog post.

    0 讨论(0)
  • 2020-12-13 15:28

    Following @Mark answer, the Swift 3 version:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
        if ProcessInfo.processInfo.arguments.contains("UITests") {
            UIApplication.shared.keyWindow?.layer.speed = 200
        }
    }
    

    On you ui test file:

    override func setUp() {
        super.setUp()
    
        // Put setup code here. This method is called before the invocation of each test method in the class.
    
        let app = XCUIApplication()
        app.launchArguments = ["UITests"]
        app.launch()
    
    0 讨论(0)
  • 2020-12-13 15:29

    I wanted to disable ALL animations during Snapshot testing. I was able to able to achieve this by disabling both Core Animation and UIView animations as below.

    Note because my app used storyboards UIApplication.shared.keyWindow was nil at launch so I access the UIWindow by referring to the window property directly.

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        if ProcessInfo.processInfo.arguments.contains("SnapshotTests") {
            // Disable Core Animations
            window?.layer.speed = 0
            // Disable UIView animations
            UIView.setAnimationsEnabled(false)
        }
        return true
    }
    
    0 讨论(0)
提交回复
热议问题