UI Tests iOS and async build of UI - ios

I'm trying to write UI test in my iOS project. The main view is built after an API call response, so when i try to test it with a UI test, after the XCUIApplication.launch(), if check existence of a UI element, test fails, maybe because the element is not already present in the view, but if i add a breakpoint before the test check, test stop correctly with a success, there's a way to test this kind of behavior?

Related

Print statement is not working in view controller method when run the UI Test case in Xcode 14.0

I have created a custom framework and inside that all the logs are recorded when we initialise the framework.
Now I have integrate that framework inside a demo project and write UI test case for the same.
When I add the breakpoint inside the method then only logs are getting printed in the console while running the UI test case .Otherwise it don't print the logs in the console when break point is not added.
I don't know why thing is happening. I need logs for analysis purpose.
Could you please help me .
Print statement is only working when adding break point in the view controller class.
![2]
Your UI test code runs in a separate process outside of your app process. The default state shows the debugger for the UI test process, and not your app process, and will only show print statements written in the UI test code. The print statement you wrote seems like it’s a part of your app code.
If you hit a breakpoint in your app code, the Xcode console switches to show the debugger for your app, as opposed to the debugger for your UI test, which is why you see the print statement there.

Can an XCTestRunner access View Controller properties of target application?

I am trying to write some smart UI tests using XCUITest. Now I want to build a test suite such that, depending on my applications ViewController I make deduce what type of testing happens. Example would be I have a monkey test running in a loop, On some view controllers of my app I would like taps on the full screen, however on other view controllers i'd like taps only on a part of the screen, With what I've seen UI tests are bundeled and run in UITestRunner and my application being tested is the target application, Is there anyway I can access properties of View Controllers of the target applications ?
No, you can not access view controller properties at run time from UI test code because the UI test runner is a separate executable to the app (where the view controller would be accessible).
UI tests are high-level integration tests for testing functionality at the UI level. You can only give input via touch and only receive output via the UI.
If you need to test something that requires access to view controller properties, you need to use a unit test. Unit tests run in the same executable environment as the app so you can access particular properties of the objects you've made.
If you want to make the UI test interact with different pages differently, think about narrowing the list of available elements to tap, and identify particular pages to further filter the list by looking for an element unique to each page. Check out the page object model for an idea about how to scale your UI tests for multiple pages.
You can try '#testable import ' to access your app. but you may never get the reference to the currently running app while running XCUI Tests by doing this.
What you should consider is writing Integration tests which will run in the app context, then you can do as below:
#testable import
let win = UIApplication.shared.delegate?.window!
let rootViewController = win?.rootViewController as <>
and then access the rootViewController and send actions to the controller and controls defined in that particular controller.
We write most of our tests this way which is more easier, faster and reliable.
Refer to the Quick Documentation Below for more details.
https://github.com/Quick/Quick/blob/master/Documentation/en-us/TestingApps.md

UI Tests Pass Manually, Fail When Ran Automatically

I am trying to run my UI Tests all at once. All the tests work fine when I run them individually, but when I run them automatically all together the tests fail because Xcode does not update where it is at in the app to successfully run the other tests.
So just to clarify, my first test is the signUpTest, so I'll run that test and it will work and then it will go to the second test which is the signUpMyInfo test. My issue is that this second test will only run once the app has moved to the second view controller, which is where the first unit test ends, however when the second test begins for some reason Xcode throws the app back to the first view controller, causing the second test to fail.
In short, I am unclear why the app returns to the first view controller after the first test successfully passes rather than remaining on the second view controller and running the second test from there.
Also worth noting, that this problem does not always happen, Xcode does sometime successfully throw me to the next view controller where the second test passes fine, but this problem is happening enough that I have to bother someone on stack to help me solve it :p
At the end of each test Xcode runs, it will close the app, and you'll need to launch the app again at the beginning of each test. This is to encourage test independence, which allows each test to stand alone, so that you know that if a test fails, it fails because of something that test did, not as a result of something another test did. This makes test failures easier to diagnose and makes your test results more informative and accurate.
You will need to add code in your second test to move from the first view controller to the second. This may seem like duplication at first glance, but as explained above, this is for the greater good of your test suite.

How to prevent app quit automatically after UI Test in Xcode?

I want to let the UI Test automatically lead me to some parts of my app, and then I will go with some manual testing. However, the app just quit automatically after the UI Test is done. Are there any ways to prevent this and achieve my goal?
For a UI test you can simply set a breakpoint at the end of the test. Once the breakpoint is hit you can go ahead and use the debug application.

How to access the App Delegate from a UI Test?

I want to access a particular property router from the App Delegate of the launched app during a UI Test, but I can't figure out if this is possible or not. I have tried:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let router = appDelegate.router
but this gives a failure and won't even build. I am using #testable on my project module. Any ideas?
Xcode UI testing is designed such that the test code can only see what a user can see, so no objects from the application under test can be used or inspected in the test code. This is also why the views on the screen are represented as XCUIElement objects instead of UIView descendants.
The UI tests run in a separate executable from the application under test. The only way to communicate additional information from the app to a UI test is by constructing a string containing the information and using it as the accessibility identifier for an element.
If you want to test something that requires access to an object from the application code, it is most likely that you need to write a unit test instead of a UI test.

Resources