In what cases can there be such a situation when unit tests will run earlier than View is fully loaded?

577 Views Asked by At

I was stumbled upon RunLoop.current.run(until: Date()) string in ViewController unit testing tutorial. In article the author wrote: “ The RunLoop.current.run(until: Date()) statement makes sure the run loop associated with the current thread has ample time to let the drawing operations to complete.

Here the code:

class CreateOrderViewControllerTests: XCTestCase
{
 // MARK: - Subject under test

 var sut: CreateOrderViewController!
 var window: UIWindow!

 // MARK: - Test lifecycle

 override func setUp()
 {
   super.setUp()
   window = UIWindow()
   setupCreateOrderViewController()
   loadView()
 }

override func tearDown()
{
   window = nil
   super.tearDown()
}

// MARK: - Test setup

func setupCreateOrderViewController()
{
  let bundle = Bundle.main
  let storyboard = UIStoryboard(name: "Main", bundle: bundle)
sut = storyboard.instantiateViewController(withIdentifier: "CreateOrderViewController") as? CreateOrderViewController
}

func loadView()
{
    window.addSubview(sut.view)  
    RunLoop.current.run(until:Date())
}

func testCursorFocusShouldMoveToNextTextFieldWhenUserTapsReturnKey()
{
// Given


// Scroll to the top of table view so the first text field is visible and can actually become first responder
let firstSectionIndex = 0
let firstRowIndex = 0
sut.tableView.scrollToRow(at: IndexPath(row: firstRowIndex, section: firstSectionIndex), at: .bottom, animated: false)

// When
let currentTextField = sut.textFields[0]
let nextTextField = sut.textFields[1]
currentTextField.becomeFirstResponder()
_ = sut.textFieldShouldReturn(currentTextField)

// Then
XCTAssert(!currentTextField.isFirstResponder, "Current text field should lose keyboard focus")

XCTAssert(nextTextField.isFirstResponder, "Next text field should gain keyboard focus")
}

I read a few articles about RunLoop, and tried to replace RunLoop.current.run(until:Date()) with RunLoop.current.run(until:Date(timeIntervalSinceNow: 30)). enter image description here and saw that all 30 seconds xcode did not proceed to the next process.

Then I conducted experiment with assigning view to window on background concurrent thread with RunLoop.current.run(until:Date(timeIntervalSinceNow: 30)).enter image description here It also didn’t call any other processes on any threads for 30 seconds, that is, the system waited 30 seconds and at that time the process that was already running, it was being finalized, and again any other processes on any threads haven't been called for 30 seconds.

Then I looked on what thread the viewController initialization and window.addSubview() processes are running - it is Thread 1 Queue : com.apple.main-thread (serial), then I looked on what thread test functions are running this is also Thread 1 Queue : com.apple.main-thread (serial). Due to it is serial it is impossible that test functions is executing before viewController initialization and window.addSubview() processes are done. But some people wrote that it could be, when and why?

0

There are 0 best solutions below