multi-platform jsunittest

1 view
Skip to first unread message

nlloyds

unread,
Feb 28, 2009, 11:44:17 PM2/28/09
to Dr Nic's JavaScript projects
I've created a branch (http://github.com/smith/jsunittest/tree/multi)
of jsunittest that can work on Rhino, SpiderMonkey, WScript, ASP, and
possibly others.

It works by setting JsUnitTest.Unit.Runner.loggerType to the name of a
Logger or passing in a loggerType option to the Test.Unit.Runner
constructor. That option is used to create the right logger (DOMLogger
by default, there's also a CLILogger in the branch, and I'm making an
HTMLLogger to output the test HTML as a string.)

The tests won't automatically run, so there's an output() method. If
window and setTimeout are present it will do what it does now (run
runTests() on window.onload), otherwise it will just call runTests().
So you can do:

var suite = new Test.Unit.Runner(...);
suite.output();

or just:

new Test.Unit.Runner(...).output();

output() will return the return value of runTests().

An aside:

The reason I need output to return a value is because in ASP (the
platform I use in my day job), server-side JavaScripts always run
first, and any calls in Response.write() in runat="server" script tags
will be written before any of the html. So, I need to do:

<html>
<script runat="server" ...load the tests
<h1>My Test File</h1>
<%= suite.output() %>
...

to make it look nice.

There's a Rake task (rake test_units_cli) that will run the tests in
test/unit/cli. It currently uses the js command (what's the best way
in Ruby to tell if a system command exists? I want it to use whichever
one is present: js or rhino.) I would like to fix up the formatting of
the output on these, but they seem to work.

Any comments about this approach? Is output() the right method name to
be using? I'd like to get any input, as I'm not attached to how I'm
doing this, but I think it could be useful to have a great unit
testing framework that works everywhere once JavaScript completes its
takeover of the universe. :)

Thanks,

Nathan

Choan Gálvez

unread,
Mar 3, 2009, 12:56:35 PM3/3/09
to drnic-javasc...@googlegroups.com
Hey Nathan.

On Mar 1, 2009, at 05:44 , nlloyds wrote:

>
> I've created a branch (http://github.com/smith/jsunittest/tree/multi)
> of jsunittest that can work on Rhino, SpiderMonkey, WScript, ASP, and
> possibly others.

That's really cool.

> It works by setting JsUnitTest.Unit.Runner.loggerType to the name of a
> Logger or passing in a loggerType option to the Test.Unit.Runner
> constructor. That option is used to create the right logger (DOMLogger
> by default, there's also a CLILogger in the branch, and I'm making an
> HTMLLogger to output the test HTML as a string.)

So, isn't it possible to use more than one logger? Maybe a publisher/
subscriber pattern would work best.

> The tests won't automatically run, so there's an output() method. If
> window and setTimeout are present it will do what it does now (run
> runTests() on window.onload), otherwise it will just call runTests().
> So you can do:
>
> var suite = new Test.Unit.Runner(...);
> suite.output();
>
> or just:
>
> new Test.Unit.Runner(...).output();
>
> output() will return the return value of runTests().

Then, if I understand correctly, tests are run automatically but the
logger is silent until output is called?

I'd like to suggest a different approach:

var myLogger = new MyCustomLogger();
new Test.Unit.Runner(tests_list_object, { loggers: myLogger });

(Where the loggers configuration property would be a logger or an
array of loggers.)

This would allow both using multiple loggers and let them decide about
output.

So, for the previous case, you would use

myLogger.output();

What do you think?
--
Choan
<http://choangalvez.nom.es/>

nlloyds

unread,
Mar 3, 2009, 7:50:56 PM3/3/09
to Dr Nic's JavaScript projects
Choan,

On Mar 3, 11:56 am, Choan Gálvez <choan.gal...@gmail.com> wrote:
> That's really cool.

Thanks!

> So, isn't it possible to use more than one logger? Maybe a publisher/
> subscriber pattern would work best.

I guess that's true, though scripts are generally only going to run in
one environment at a time, though it would be cool to have a test run
in the browser and save another copy to a file, for example. The only
problem I see it that environments that don't have a window object
will choke when trying to use the DOM, so that logger would have to be
modified to not run if it didn't have the proper objects and methods
present.

> > The tests won't automatically run, so there's an output() method. If
> > window and setTimeout are present it will do what it does now (run
> > runTests() on window.onload), otherwise it will just call runTests().
> > ...

I've revisited this and I think I'll make it behave the way it does in
the master branch now (running everything when the Runner object is
created), but only add the onload event if the capabilities to do that
exist.

> I'd like to suggest a different approach:
>
> var myLogger = new MyCustomLogger();
> new Test.Unit.Runner(tests_list_object, { loggers: myLogger });
>
> (Where the loggers configuration property would be a logger or an
> array of loggers.)
>
> This would allow both using multiple loggers and let them decide about
> output.
>
> So, for the previous case, you would use
>
> myLogger.output();
>
> What do you think?

That's a good idea, and I think I'll try that approach.

One thing I was trying to get around is being able to specify the
logger being used after the Runner is created. If you look at my
branch, you'll see the .js files in /test/unit have only the tests,
and there are subdirectories for cli, jaxer, asp, dom, wscript, etc.,
which load the same tests in their parent directory and set the output
format and supporting html, etc. for that particular platform.

Another thing I think I'll add is a resultsString (or some other name)
property that collects the results from all of the tests into a
string, so in ASP I can do <%= suite.resultsString %> and output the
results into the page.

Thanks for your comments.

Nathan
Reply all
Reply to author
Forward
0 new messages