Search code examples
swiftios11xcode9xctestxcode-ui-testing

How to trigger another method or task based on testcase failure or skipped or pass in xctest framework


I am writing UI test cases in swift using xctest framework.

I want to trigger another task(such as taking screenshot or ) based on testcase pass or fail or skip. My current code is below

  import Foundation
  import XCTest

  class HomePageChromeUITests: XCTestCase {

var pathStr:String = ""
override func setUp() {

    super.setUp()
    continueAfterFailure = false
    self.launchWithUserLoggedIn()
}

override func tearDown() {
    super.tearDown()
}

func testHomePageChrome_10385() {
    let app = XCUIApplication()


    let backButton = app.buttons[AccessibilityIdentifiers.PageEditorBackButton]
    let editButton = app.buttons[AccessibilityIdentifiers.PageEditorEditButton]

    XCTAssertTrue(backButton.exists && backButton.frame.origin.x < editButton.frame.origin.x, "Back button does not exist.---10385")
    XCTAssertTrue(!editButton.exists, "Edit button does not exist.---10385")

 }
}

I want to trigger a method whenever testcase fails and pass my failed message there That is "10385".

How can i achieve this. Any help would be appreciated.


Solution

  • In XCode 9 Apple changes its previous XCTestObservation to XCTestObservationCenter. You will find the reference here

    To do something based on the TC pass or fail you need to register the testObserver and add it to your test.

    Here is the complete implementation for this.

    Step 1: Create a class called observer.

     import Foundation
     import XCTest
    
     class Observer: NSObject, XCTestObservation {
    var failedTC = 0
    
    func testBundleWillStart(_ testBundle: Bundle) {
        print("Test bundle started")
    }
    
    func testBundleDidFinish(_ testBundle: Bundle) {
        print("Test bundle Finished")
    }
    
    func testSuiteWillStart(_ testSuite: XCTestSuite) {
        print("Test suite started")
    }
    
    func testSuiteDidFinish(_ testSuite: XCTestSuite) {
        print("Test suite ended")
    }
    
    func testSuite(_ testSuite: XCTestSuite, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: Int) {
        print("Test suite failed, information: " + description)
    }
    
    func testCaseWillStart(_ testCase: XCTestCase) {
        print("Test case started")
    }
    
    func testCaseDidFinish(_ testCase: XCTestCase) {
        print("Test case finished")
    }
    
    func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: Int) {
        print("Test case failed. Message: " + description)
    
        var tmpMsgArr = description.components(separatedBy: ".---")
        let testcaseID = tmpMsgArr[0]
    
        print("------" + testcaseID)
    
        yourAwesomeMethodThatWillbeCalledWhenTCFails() // implement this method that you want to execute
    
        failedTC += 1
    }
    
    }
    

    Step 2: Add this observer to your test. For adding observer code is here.

      let observer = Observer() // Your created observer class
      let observationCenter = XCTestObservationCenter.shared()
      observationCenter.addTestObserver(observer)
    

    Note: Remove the observer when you break down your tests or you will get multiple invocations and multiple calls on test events if you add an observer on every setUp.

    In your case rewrite your set up method like below:

     override func setUp() {
    
        super.setUp()
        continueAfterFailure = false
    
        let observer = Observer() // your created observer class
        let observationCenter = XCTestObservationCenter.shared()
        observationCenter.addTestObserver(observer)
    
        self.launchWithUserLoggedIn()
    }
    

    Hope this complete example will help you.