1

I am starting to pick up XCUITest and I am running into an issue. I know a little about Objective-C / Swift. Enough that I have built a simply CRUD app in the past. The issue I am running into is outlined below.

Cannot find 'app' in scope

I believe this has to do with declaring this and a class existing, but I am not 100% sure what I am missing here. Please go gentle on me. I have included my code below as well.

class CandySearchUITests: CandySearchUITestsLaunchTests {
    
    func testTapOnChocolateBarItem() throws {
        
        // Asset Candy Search Logo Exists (Acessibility Identifier)
        XCTAssertTrue(app.images["candySearchLogo"].exists)
        
        // Tap Chocolate Bar item (Table - Static Text)
        app.tables.staticTexts["Chocolate Bar"].tap()
        
        // Assert it landed on the Chocolate page (Navigation Bar - Static Test)
        let chocolateNavigationBar = app.navigationBars["navigationBar"]
        XCTAssertTrue(chocolateNavigationBar.staticTexts["Chocolate"].exists)
        
        // Assert Chocolate Bar title exists (Static Text)
        XCTAssertTrue(app.staticTexts["Chocolate Bar"].exists)
        
        // Return to Candy Search Screen (Button)
        chocolateNavigationBar.buttons["Back"].tap()
        
        // Assert Candy Search Logo exists (Accessibility Identifier)
        XCTAssertTrue(app.images["candySearchLogo"].exists)
    }
}

I also noticed that I am getting 'Inheritance from a final class 'CandySearchUITestLaunchTests' however, I know why I was getting that error. That has been resolved.

Included my code from CandySearchUITestLaunchTests

import XCTest

class CandySearchUITestsLaunchTests: XCTestCase {

    override class var runsForEachTargetApplicationUIConfiguration: Bool {
        true
    }

    override func setUpWithError() throws {
        continueAfterFailure = false
    }

    func testLaunch() throws {
        let app = XCUIApplication()
        app.launch()

        // Insert steps here to perform after app launch but before taking a screenshot,
        // such as logging into a test account or navigating somewhere in the app

        let attachment = XCTAttachment(screenshot: app.screenshot())
        attachment.name = "Launch Screen"
        attachment.lifetime = .keepAlways
        add(attachment)
    }
}```
Martin
  • 311
  • 1
  • 2
  • 20
  • 1
    Did you forget the `@testable import` of your app? – timbre timbre Sep 21 '22 at 17:13
  • 1
    The first error seems pretty obvious. You're inheriting from a `final class`. On a class, `final` means you can't inherit from it. On a method, it means you can't override it when inheriting from the class that declares it `final`. – Chip Jarred Sep 21 '22 at 17:13
  • Assuming that `app` is defined in `CandySearchUITestsLaunchTests`, failure to find it may be an artifact of the fact of the error that you can't inherit from it, but check to see if you defined `app` as `private`, if you did, then nothing outside of `CandySearchUITestsLaunchTests` can see it, including subclasses. Change it to `internal` or re-think your test design so you don't need to access it from the subclasses. – Chip Jarred Sep 21 '22 at 17:22
  • Added the code from ```CandySearchUITestsLaunchTests``` – Martin Sep 21 '22 at 18:01
  • 1
    `app` is a local variable in the `testLaunch()` method. You'd need to make it property of `CandySearchUITestsLaunchTests` if you want to access it from subclasses (or even other methods in `CandySearchUITestsLaunchTests`) – Chip Jarred Sep 21 '22 at 18:07
  • Also if you're intention is to make `app` available for your tests, you'd want to launch it in `setupWithError()`. – Chip Jarred Sep 21 '22 at 18:10
  • I haven't done much with UI tests, but I imagine you'd need to add a `tearDown()` method to quit app after test are done too. – Chip Jarred Sep 21 '22 at 18:12
  • @ChipJarred there is a default `tearDown()` called; unless you need to do something custom, it can be relied on. – Mike Collins Sep 22 '22 at 12:35
  • @ChipJarred I think you've nailed the problems here. Could you create them as an answer? 1) inheriting a `final` class 2)` app` is defined in a function and 3) it is better practice to `launch()` in setup as opposed to in every test. – Mike Collins Sep 22 '22 at 12:38

0 Answers0