iOS Unit Testing and UI Testing Tutorial

Hi Audrey, thank you for this tutorial. I just started going through the Unit Testing section, and had this error:

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

at line 45 of BullsEyeGame.swift

targetValue = 1 + (Int(arc4random()) % 100)

Changing the code to below resolved the error.

targetValue = 1 + Int(arc4random() % 100)

Hope this helps any developers stuck at this point :slight_smile:

Thanks for the tutorial, Audrey.

When running test_UpdateSearchResults_ParsesData()

In SearchViewController’s updateSearchResults() method, there’s a fatal error when self.tableView.reloadData() is called.

In the console: fatal error: unexpectedly found nil while unwrapping an Optional value
Inspecting self.tableView in the debugger at line 103, (screenshot), shows that it’s nil

I tried stepping through the test to see if there was a particular line that was causing this, and found that doing so usually resulted in the error not occurring. The one time that it still occurred, there didn’t seem to be a particular line in the test that was causing it, as though it was just a “side-effect”?

I didn’t change a thing in the HalfTunes app I downloaded from your link, and I’ve gone back over the code I typed from the tutorial and everything looks right. Anybody else see this? Thanks
 Jerry

1 Like

thanks xared! I’m not sure why you got that error, but it’s good you found a fix.

the original code still works for me

hi Jerry: yes, I now get the same experiences as you did; probably an Xcode 8 bug that changes the meaning of instantiateInitialViewController, so it doesn’t set up the view controller properly?

anyway, the SUT for this test shouldn’t be the view controller, as it isn’t testing anything in the view; I’ve attached the version I demo in my URLSession video course, where the networking code is in an APIManager class. The parse test runs without the tableView error.

HalfTunes-APIManager.zip (47.9 KB)

2 Likes

Thanks for the reply and code, Audrey.
I’ll check it out.

Jerry

Hi audrey

Loved this article. Could you provide Alamofire implementation of Testing asynchronous requests? That would be a great help.Thanks.

sorry, I had a look around to see if anyone has done this, but no luck. Have you tried just using the most-similar AF calls?

update: I found this

Hi Audrey, thanks a lot for the article. It really help me get better understanding of testing. However, I got the same problem when reloading search results. It turns out tableview didn’t initialized after initializing SearchViewController from Storyboard. It seems that apple do some setups in view’s getter. Adding below code in setUp() do the trick.

_ = controllerUnderTest.view 

Here are some discussion with testing viewController.

https://www.natashatherobot.com/ios-testing-view-controllers-swift/

Thanks again for the great tutorial :slight_smile:

2 Likes

thanks Jenny! I actually saw that post, but didn’t make the connection, or thought it wasn’t relevant anymore :blush:

Thanks audrey for the article. I have been looking into XC UI testing for some time and found this article very helpful. Have you tried setting userdefaults of the application which is being tested while performing xc testing?

Thank you so much Audrey for such a clear and precise tutorial! It helped me to jump start on this topic.

1 Like

Just a very minor correction, in BullsEyeTests setup() function, following gameUnderTest = BullEyeGame(), the line “gameUnderTest.startNewGame()” should be removed. Because in Swift, the constructor BullEyeGame() calls init() by default and it calls startNEwGame() already. Thanks again Audrey for such a good tutorial!

1 Like

There’s a section in our Mocking Objects tutorial — Mocking Apple Framework Classes — about mocking notifications or user defaults, to test your app’s interaction with these classes.

I used the author’s DHURLSessionMock.swift in this tutorial.

Hi Audrey,

I have one doubt regarding mock networking Unit Test, In the given example above if I change the mock URL and asynchronous url in test method still the test method passes. I guess It should need to fail. Any Idea?

// In the setUp method URL is different as of
override func setUp() {
super.setUp()
let url = URL(string: “http?media=music&entity=song&term=abba”)

}

// Asynchronous method URL

func test_UpdateSearchResults_ParsesData() {

// when
XCTAssertEqual(controllerUnderTest?.searchResults.count, 0, “searchResults should be empty before the data task runs”)
let url = URL(string: “/music&entity=song&term=abba”)

}

Thanks in advance!!
Regards,
Ankit Garg

hi Ankit: you can set up the mock response to either succeed or fail; in the exercise, you’re testing whether the app handles a correct JSON response correctly. You could also test whether the app handles error responses from the server correctly, by configuring a suitable mock response. The URL doesn’t actually matter, because your test isn’t accessing a real server.

I’m experiencing the same issue.

I’ll note though I was getting a crash when trying to load abba json file from try? Data and noticed it wasn’t included in target membership and so included it. Now it’s the reload crash. I presume because the tableView isn’t initialised for some reason.

hi Sean: I saw a tweet recently, complaining that Xcode seems to be defaulting to not setting target membership, and I got caught by it once or twice while working with 9 beta.

For the nil tableView problem, see Jenny’s (jt1120) post #28 from June 30, above:

_ = controllerUnderTest.view

This tutorial is more than six months old so questions regarding it are no longer supported for the moment. We will update it as soon as possible. Thank you! :]