3

I'm trying to break up my UIAutomation test scripts into chunks, to make it possible to run them one piece at a time or all together. So I have a structure:

all-tests.js:

#import "tab-dates.js"
#import "tab-temperatures.js"

tab-dates.js:

#import "../../../Libraries/tuneup_js/tuneup.js"
#import "dpl_assertions.js"

var target = UIATarget.localTarget();
var app = target.frontMostApp();

test("Verify date view is shown", function() {
    assertEquals(tabBar.selectedButton().name(), "Date");
});

Both of these live in the same directory, and are imported into an automation trace file that also lives in the same directory.

When I run tab-dates.js directly, everything is fine. tuneup.js is found, path is correct, test passes. But when I try to run all-tests.js, I get:

Script threw an uncaught JavaScript error: Can't find variable: test on line 8 of tab-dates.js

It's not a straight path problem, because if I edit the script to break the path I get a different error that explicitly says 'file not found'.

As far as I can tell, chaining imports is supposed to work -- I mean, this is the entirety of tuneup.js (https://github.com/alexvollmer/tuneup_js):

#import "assertions.js"
#import "lang-ext.js"
#import "uiautomation-ext.js"
#import "screen.js"
#import "test.js"
#import "image_assertion.js"

So I have the weird situation that

  • tab-dates.js imports tuneup.js imports test.js => OK
  • all-tests.js imports tab-dates.js imports tuneup.js imports test.js => NOT OK

What's going on?

c roald
  • 1,984
  • 1
  • 20
  • 30
  • 1
    This is a known bug in UI Automation: http://www.openradar.me/12567752 – Jonathan Penn Jul 26 '13 at 15:27
  • One advice - forget UI Automation and never go back. UI Automation is not good enough to write stable tests and if your tests cannot be stable, it doesn't make sense to even write them. – Sulthan Mar 04 '15 at 21:47

2 Answers2

2

TL;DR the initial script you run is special. To work around this, create an initial script that includes exactly one other script, and then these general rules apply:

  • imports are done in the order they appear in a file
  • a script will first execute, then do its imports
  • imports are done depth first
  • a script imported once will not be re-imported

However, the initial script does not obey these rules.

I spent some time figuring this out by creating four scripts: one.js; two.js; three.js and other.js, where one.js imports two.js; which imports three.js; which imports one.js and they all import other.js. Apart from the import, the scripts log their name, like so:

#import "two.js";
#import "other.js";
UIALogger.logMessage("one.js");

If I then run one.js, the output I get is

2015-03-04 21:21:20 +0000 Default: two.js
2015-03-04 21:21:20 +0000 Default: three.js
2015-03-04 21:21:20 +0000 Default: one.js
2015-03-04 21:21:20 +0000 Default: other.js
2015-03-04 21:21:21 +0000 Default: one.js

Then I created a script called launch.js, that imports one.js and nothing else. When I run this script, the output I get is:

2015-03-04 21:27:59 +0000 Default: one.js
2015-03-04 21:27:59 +0000 Default: two.js
2015-03-04 21:27:59 +0000 Default: three.js
2015-03-04 21:28:00 +0000 Default: other.js
2015-03-04 21:28:00 +0000 Default: launch.js

From this we can deduce that:

  • the initial script called will first do its imports, then execute
  • the initial script will be re-imported and run if imported by other scripts, exactly once
  • imports are done depth first

So use the launch.js strategy to reduce pain in your life.

0

As Jonathan Penn said this is a known bug but you can create a header file that imports all the necessary files for your tests, and then import that header file at the beginning of whatever script runs first.

Braains
  • 606
  • 1
  • 5
  • 22