16 Apr 2013, 01:55
Generic-user-small

Eric Turner (6 posts)

Hi Jonathon - I’m working on a complex enterprise iPad project. I was fairly recently able to get a couple of suites of UI Automation tests running from a shell script, largely with the help of yours and Alex Vollmer’s work and code examples. Big thanks for that.

The beta portion of your book and code examples have really helped me reach a new level of organization and understanding. Thank you again!

Here’s the situation: I have a collection view of items which represents the current state of a department. A user selection of one of the items, or an “Add New” button event, presents a modal view controller for the editing and configuration of an item. The modal view is a tableView controller which drills into child detail controllers for configuring many of the item’s properties.

There are sufficient features in the modal view for its own suite of tests, and there are likewise a sufficient number of tests of collectionView features for its own suite of tests.

The question is: I want to encapsulate a suite of tests for the modal view controller operations. I want the collectionView tests to start, and as part of the collectionView tests, to present the modal view and hand off control to the modal view test suite. Then control should pass back to the collectionView tests when the modal view is dismissed. Is there a good way to do that?

I hope I’ve described what I’m trying to accomplish clearly enough.

16 Apr 2013, 03:04
Avatar_pragsmall

Jonathan Penn (43 posts)

I think I understand what you’re getting at. I must apologize up front if my solution is quite general, I have to make some assumptions without actually looking at your code.

That said, faced with what you’re describing it sounds like the simplest way would be to break out your modal view controllers and just put them in a named function of some kind and call that within a a function that does your collection view controller steps.

Here’s a quick pseudocode sketch:

function stepsForCollectionViewTests() {
   // ...
   stepsForModalViewTests();
   // ...
   // Do other stuff
}

function stepsForModalViewTests() {
   // ...
}

We’re in straight JavaScript here so you can mix and match this any way you want. Break these out into separate files and @#import@ them anywhere you want.

If you’ve reached chapter 4 (Organizing Test Code), you’ll see how I like to express the semantics of my applications as Screen objects that let me do things like:

SearchTermScreen.addTerm("coffee");
SearchTermScreen.assertFirstTermIs("coffee");

Do you think you could describe the portions of your app that use collection and modals views this way? What if you had a @DepartmentScreen@ object that had an @addNew@ method on it. That method would know how to manipulate the modal view controller, or would know who to delegate to.

Let me know if this helps or not. I think this is a great question.

16 Apr 2013, 05:04
Generic-user-small

Eric Turner (6 posts)

Thanks for the quick reply. I see your idea and it definitely looks viable.

The biggest part of the refactor of my previous work as a result of reading your book is exactly incorporating the semantics of Screen objects. As I said, my project is complex, with many deep view hierarchies and even view controller hierarchies.

Here’s how I have organized so far; maybe I’m making it too complicated. I have a ServerLoginScreen.js which provides functions for accessing and typing into the username/password fields, and pressing the login button. The test_server_login.js is the “suite” of assertions of the form:

test("ServerLogin: Test both login textfields with blank values displays failure alert", function () { 
    // steps to clear textfields, 
    // enter blank username/password values, 
    // assert non-nil alert.
}
//... more fail tests
// .. test user credential login pass combinations
// .. login successfully to proceed to collectionView

which test for various combinations of fail login attempts and for an expected successful login. For a successful login event, the server login view controller is swapped out for the collectionView controller.

Then there is a MyCollectionViewScreen.js which exposes methods for scrolling to and selecting a specific collectionViewCell, longPress gesture on the cell for the display of an actionSheet, etc. One of the actionSheet options is to present the modal view for editing cell data. There is also a top left bar button which presents the modal view for an “Add New Item” operation, in which the modal view data and behavior differ somewhat. The current suite of tests which are run against the MyCollectionViewScreen are in test_collectionView.js

So far, all the tests which run in test_server_login.js and in test_collectionView.js are wrapped in “runAllServerLoginTests()” and “runAllCollectionViewTests()” functions. The shell script which executes the Xcode build and launches Instruments defines the path to a “master” script, “automation_tests.js”, which currently has these lines:

"use strict";
#import "env.js";

runAllServerLoginTests();
runAllCollectionViewTests();

This app implements a specific interface and data to support the workflow of more than one user role within the department. So, I’m trying to modularize the testing into “suites” and “screens”.

The (I guess I’ll call it) nested approach you describe with pseudocode definitely looks viable. The collectionView and modal view features are interrelated and could be, and perhaps should be, considered as a unit.

Sorry for the verbosity. I’m really looking forward to the rest of the book, and thanks for the feedback!

16 Apr 2013, 16:12
Avatar_pragsmall

Jonathan Penn (43 posts)

Sounds like you’ve got a good plan. There’s a lot of flexibility here to organize the code. JavaScript gives us decent options. This is how I would start attacking the problem, too!

  You must be logged in to comment