-1

I am writing a test in XCUITest. There is an introductory banner which may or may not come on the mobile screen while my test is in progress. I want to write my case in such a way that, if the banner is present, I have to verify certain elements on that banner and click on the "Continue" button on it, and if it is not present, I have to proceed with my test case.

I know in Java, we write such code inside a try-catch block, so that even if the banner is not found and the code fails, the pointer goes into the catch block and the remaining program continues.

When I searched on the internet, i only found such feature for single statements and not for some chunk of code block.Do we have something similar in Swift, where I can write some code inside try-catch like code block? Please have a look at my test case and the code to click in the banner.

class MyTestClass: BaseTest {
    func testMapSearch() {
        do {
            let app = try XCUIApplication()
            let element = try app.children(matching: .window).element(boundBy: 0).children(matching: .other).element.children(matching: .other).element(boundBy: 1).children(matching: .other).element(boundBy: 0)
            element.buttons["Continue"].tap()
        } catch let error {
            print("Error: \(error)")
        }

        let logInButton = app.scrollViews.otherElements.buttons["Log In"]

        checkLoginPage(login: logInButton)
        logInButton.tap()
    }
}

The do block is written to click on the "Continue" button on a banner which is not sure to be displayed on the screen. The do block is followed by more code. If the banner is not displayed, the code written in the do block fails and the test case throws an error. I want to write a case such that the login button code should get executed irrespective of the banner is displayed or not.

rmaddy
  • 298,130
  • 40
  • 468
  • 517
Amit Jathar
  • 177
  • 10
  • Please have a look at my answer here: https://stackoverflow.com/questions/32758811/catching-nsexception-in-swift/36454808#36454808 – freytag Aug 22 '18 at 21:16
  • Please read the [Error Handling](https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html) chapter in the Swift book. – rmaddy Aug 22 '18 at 21:16
  • The above code fails where? With what exception? Note that in Swift there is a huge difference between error and exception. It's much different than in Java. – rmaddy Aug 23 '18 at 17:25
  • You didn't answer my question. Which line fails? What is the actual exact error? Is the `print` in your `catch` being called or not? – rmaddy Aug 23 '18 at 17:52
  • @rmaddy, the test fails at: element.buttons["Continue"].tap() line. And the print statement in the catch block is not executed. The error is: t = 6.66s Find the "Continue" Button t = 7.70s Find the "Continue" Button (retry 1) t = 8.73s Find the "Continue" Button (retry 2) t = 8.80s Assertion Failure: MyTestClass.swift:18: No matches found for Find: Elements matching predicate '"Continue" IN identifiers' from input {( – Amit Jathar Aug 23 '18 at 19:02

1 Answers1

1

The problem with your code is that the two lines of code marked try are not failable (they don't throw), so you cannot mark them try in the first place.

The entire attempt to turn this situation into a try/catch is wrong-headed. What you want to do here is simply add a condition to check whether the desired element exists and is tappable, and proceed differently if it doesn't (i.e. don't attempt to tap it). That is what if is for.

(Of course one might argue that if the test is not intended to fail if it is impossible to tap this element, then the test itself is incorrectly constructed — you should just omit the tap line altogether.)

matt
  • 447,615
  • 74
  • 748
  • 977