Unit Test Segues in Swift 4+

December 30, 2018 ยท 2 minute read

This test assumes that you are using a storyboard. In the test setup() method, you will setup the controller that is in the storyboard, using a guard statement in case something bad happens, and then set up the view.

You can use an undocumented API to get the segues and then you can write your tests like this:


class MyViewControllerTests: XCTestCase 
{

	var sut: MyViewController!

	override func setUp() 
	{
		super.setUp()

		guard let controller = UIStoryboard(name: "Main", bundle: Bundle(for: MyViewController.self)).instantiateViewController(withIdentifier: "MyViewController") as? MyViewController
		{
			return XCTFail("Failed to instantiate ViewController from storyboard")
		}
	
		sut = controller
	
		let _ = SUT.view
	}

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

	func testSegues_Exist() 
	{
		let identifiers = segues(ofViewController: sut)
		XCTAssertEqual(identifiers.count, 2, "Segue count should equal two.")
		XCTAssertTrue(identifiers.contains("ExitSegueIdentifier"), "Segue ExitSegueIdentifier should exist.")
		XCTAssertTrue(identifiers.contains("ShowDetailViewController"), "Segue ShowDetailViewController should exist.")
	}

	// MARK: - Helper Methods

	func segues(ofViewController viewController: UIViewController) -> [String]
	 {
		let identifiers = (viewController.value(forKey: "storyboardSegueTemplates") as? [AnyObject])?.compactMap({ $0.value(forKey: "identifier") as? String }) ?? []
	
		return identifiers
	}

}

[Subscribe to my email list](https://mailchi.mp/c9c01dee899a/welcome-new-ninja) for a monthly newsletter and special updates! 

Buy me a coffeeBuy me a coffee