9

I have a UI test like so :

    func testHome(){
         if(isRedOrange.clear()){
                //code
            }
    }

How would I access my isRedOrange.clear function from my isRedOrange.swift file from my UI tests?

user1118321
  • 25,567
  • 4
  • 55
  • 86
Helosy
  • 339
  • 1
  • 6
  • 14
  • Possible duplicate of https://stackoverflow.com/questions/37754696/uitest-color-of-a-label-not-ui-label – matt Aug 11 '18 at 20:15

4 Answers4

23

UI Tests are black boxed, so you cant have access to your code.

You can use @testable import in Unit Tests, so full access will be provided. When you're running UITests this is not working, because during a UITest your test class cannot access your app's code.

From Apple's Docs:

UI testing differs from unit testing in fundamental ways. Unit testing enables you to work within your app's scope and allows you to exercise functions and methods with full access to your app's variables and state. UI testing exercises your app's UI in the same way that users do without access to your app's internal methods, functions, and variables. This enables your tests to see the app the same way a user does, exposing UI problems that users encounter.

You must achieve everything using .tap()'s on elements. .accessibilityIdentifier will help you to get the right element

Unreal Developer
  • 485
  • 3
  • 11
  • 1
    It really surprises me that one can't define the data or flow of the app from the test suite. What Apple seem to be pushing people towards is what I think of as integration testing, whereas I want to write atomic tests which will test parts of the app's UI based on a supplied view model, and I don't want to have to re-write my queries if I happen to change the app flow. – Olivier Butler May 20 '22 at 13:31
8

Goto projects settings -> Select uitests target -> build phases tab -> add your swift file to compile sources

snake_plissken
  • 109
  • 1
  • 2
  • 5
    That worked for. Just wanted to use some existing model structs to pass some test data in. – David Mayes Sep 21 '19 at 08:01
  • 1
    I was wondering if this really works. As I understood Ui Tests and the app are like 2 different applications running side by side. So will adding a file to a second app will remove the syntax errors? yea... but will have any impact on the main app ? won't this just execute code @ the "ui project" rather than having any affect in the app we are testing? – João Serra Mar 07 '22 at 17:13
  • 1
    @JoãoSerra that's correct. The UI tests and the app are compiled separately, so the tests cannot, for instance, directly call a function within the app. You can, however, make source code available to both the app and the tests (as this answer explains). Then the tests and the app can share algorithms and data structures. They still run separately though. – saintamh Aug 04 '22 at 12:08
  • Another way is to open the specific files to use with the test target, go to the File Inspector (right panel of Xcode) and under Target Membership tick the test target – Dan Jun 26 '23 at 03:40
  • @Dan If I do that I get build errors "Undefined symbol: ...". – acmpo6ou Jul 12 '23 at 19:02
3

You need to import your main module (project) into tests:

  • Ensure you've set ENABLE_TESTABILITY in Build Settings of the main project target to true.

enable_testability

  • To import it into tests, call @testable import MAIN_TARGET_NAME in your UITests file.

enter image description here

S2dent
  • 939
  • 6
  • 9
-1

The question makes no sense. You don’t access any of your app’s code in a UI test. If you want to access your code, write a unit test.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • In my case, I needed to mock `NSOpenPanel` to provide a consistent output in UI tests, so I defined a protocol and extended `NSOpenPanel` to adopt it. I also defined a mock class in my UI Test target that also adopts the protocol. The protocol definition needs to be available to both the app and the UI tests. I just moved the protocol to its own source file and set its "Target Membership" to both app and UI tests. – Nicolas Miari Mar 25 '19 at 08:11
  • Wait, I realized can't inject my mock class from the UI test target anyway... I have to somehow determine whether I am being UI-tested from the app itself (and use either `NSOpenPanel` or mock its behavior and returned URL). The app code really is inaccessible from the UI Test target. Makes perfect sense though, since UI tests are based on macOS's accessibility features... – Nicolas Miari Mar 25 '19 at 08:34