Testing storyboard segues

34 views
Skip to first unread message

JM

unread,
Jul 15, 2015, 2:02:07 PM7/15/15
to cedar-...@googlegroups.com
I have a storyboard with a couple of segues, in my cedar spec file, I'm instantiating the VC and trying to test a segue. 

It(the VC) has a close button, that when tapped should prepare a segue back to the root view controller, in the simulator this works fine but in my cedar specs I never see prepareforSegue being called. My theory is that the VC isn't in the context of the storyboard and does not get called.. 

I don't see anything specific to storyboards in the documentation.

Sam Coward

unread,
Jul 15, 2015, 3:21:22 PM7/15/15
to cedar-...@googlegroups.com
Are you instantiating it from a UIStoryboard of the storyboard file in question?

When I work with storyboards, I usually use add identifiers to every scene and load them under test from the storyboard with -[UIStoryboard instantiateViewControllerWithIdentifier:]

--
You received this message because you are subscribed to the Google Groups "Cedar Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cedar-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

JM

unread,
Jul 15, 2015, 3:28:30 PM7/15/15
to cedar-...@googlegroups.com
Yes - I am.. Most test cases work fine and I cedar knows what everything in the VC.

My test cases tests for the VC getting dismissed, which happens through an unwind segue.. I can have cedar tap the button that should call that segue, but nothing about the segue actually happenes(prepareForsegue/performSegue)..

Even if I manually call perform segue, it doesn't seem to actually perform it and remove the viewcontroller.

Andrew Kitchen

unread,
Jul 15, 2015, 3:41:21 PM7/15/15
to cedar-...@googlegroups.com
It sounds like the view controller was not retrieved from the storyboard -- this is necessary in order for its segues to be wired up properly.

Could you please share some code to illustrate the issue?

JM

unread,
Jul 16, 2015, 9:19:38 AM7/16/15
to cedar-...@googlegroups.com
navigationController =  [[[UIStoryboard storyboardWithName:@"onboarding" bundle:nil] instantiateInitialViewController] retain];
root
= navigationController.viewControllers[0];
spy_on
(root);
[root performSegueWithIdentifier:@"joinSegue" sender:root];
joinController
= navigationController.viewControllers[1];
spy_on
(joinController);
joinController
.view should_not be_nil;
[joinController viewDidLoad];
[joinController performSegueWithIdentifier: @"exitSegue" sender: joinController];
NSLog(@"================> %@", navigationController.viewControllers);


So, my exitSegue will unwind back to the root of the navigation controller and in my test I'm expecting the navigationController.viewControllers to no longer include joinController.


I could remove the viewcontroller in my prepareFor Segue, but this method is never called when Cedar calls performSegue. 


Would removing the VC from the stack in prepare for segue and adding a prepare for segue call in the test be a valid test for checking that the VC was dismissed?

Andrew Kitchen

unread,
Jul 16, 2015, 12:56:23 PM7/16/15
to cedar-...@googlegroups.com
I was able to set up a segue with an identifier in a storyboard, trigger it programmatically in a spec and assert on the side effects of the segue.  So I'm not sure what's different about your code or storyboard.

I'm guessing your joinSegue is performing as expected, given what you have said so far and what's in the code you shared.  So is there something different about the exitSegue?  perhaps it is being requested of the wrong controller?

It is interesting to note that UINavigationController manages its navigation stack async in iOS 8+.  So you will either need to manage the animated flag yourself somehow, or use a test helper such as https://github.com/pivotal/PivotalCoreKit/blob/master/UIKit/SpecHelper/Stubs/UINavigationController%2BSpec.m.  Or you need to advance the run loop but this is generally discouraged as it will reduce the determinism in your specs.

Also, as an aside, you should never need to call viewDidLoad directly.  It is the side effect of loading the view; [subject.view layoutIfNeeded]; or subject.view should_not be_nil; will cause this to be called if the view is not already loaded.

Anyways, just a few thoughts there.  I'm not sure what is different here that is causing your one segue to not perform in your specs.

John Mejia

unread,
Jul 16, 2015, 1:52:32 PM7/16/15
to cedar-...@googlegroups.com
Thanks - The difference in segues is that exitSegue is an unwindSwgue.. Other than that I don't see what other difference it makes.


--
You received this message because you are subscribed to a topic in the Google Groups "Cedar Discussion" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cedar-discuss/PC7BTDs_B7w/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cedar-discus...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages