Search code examples
iosunit-testingswift3xcode8ios10

UI Testing with XCUI


I'm trying for unit testing of view controllers in xCode 8. I'm able to record, assert and run it successfully using XCUI. But I want to test particular view controller independently.

Like there are 4 controllers A,B,C and D in sequence (A->B->C->D). I want to directly launch C controller and test it independently.

I'm able to test in this way i.e. default XCUIApplication will open A controller then click on something you will go to B Controller and then click on button in B will take you to C Controller. Then you can test it out. But I don't want in sequence. I want to directly test C controller.

Can you please help if anyone else has done same kind of job. Thanks in advance.


Solution

  • In XCUITest with Xcode

    If you using UITestCase now, you can't directly open D controller

    everytime should do sequence (A->B->C->D) because all test case spec cause app launching espectially SignIn, SignOut should be needed for UITest every time

    supplementary way to use XCUI Test for testCase

    provide A, B, C's sequence function as protocol for minimizing duplicated code

    ex) define Login protocol

    protocol Loginable {
        var app: XCUIApplication! { get }
        func login()
    }
    
    extension Loginable {
        func login() {
            //do login ... typting textfield , tap login button
        }
    }
    

    extend your A,B,C,D UITestCase using Loginable to remove duplicated code (because every D uitest case should be logined in example)

    make extension for sequence function to reuse every case

    alternative solution is

    use KIF Functional Test framework

    KIF can test UITest based on XCTest instead XCUITest

    KIF can access your class like unit test that means

    you can show your D ViewController to window (set rootViewController directly) and test KIF UItest function

    ex) KIF

    import XCTest
    
    @testable import YourApp
    class DViewControllerTests: XCTestCase {
    
        var sut: DViewController!
        var window: UIWindow!
    
        override func setUp() {
            super.setUp()
    
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            window = appDelegate.window
    
            sut = //Initialize your D ViewController
            window.rootViewController = sut
            RunLoop.current.run(until: Date()) // cause viewDidLoad
        }
    
        func testSomeCase() {
            tester().tapView(withAccessibilityIdentifier: "someIdentifier")
            ...
        }
    }
    

    KIF can directly launch D controller setting rootViewController to window