Thanks to visit codestin.com
Credit goes to past.justatheory.com

Attention! You’re reading history

This is the past design for Just a Theory, and no longer updated. It's provided mainly for historical reasons. You probably want to read the current site.

TestSimple 0.03 Released

I'm pleased to announce the third alpha release of TestSimple, the port of Test::Builder, Test::Simple, and Test::More to JavaScript. You can download it here. This release has the following changes:

  • Removed trailing commas from 3 arrays, since IE6/Win doesn't like them. And now everything works in IE. Thanks to Marshall Roch for tracking down and nailing this problem.
  • isNum() and isntNum() in TestBuilder.js now properly convert values to numbers using the global Number() function.
  • CurrentTest is now properly initialized to 0 when creating a new TestBuilder object.
  • Values passed to like() and unlike() that are not strings now always fail to match the regular expression.
  • plan() now outputs better error messages.
  • isDeeply() now works better with circular and repeating references.
  • diag() is now smarter about converting objects to strings before outputting them.
  • Changed isEq() and isntEq() to use simple equivalence checks (== and !=, respectively) instead of stringified comparisons, as the equivalence checks are more generally useful. Use cmpOk(got, "eq", expect) to explicitly compare stringified versions of values.
  • TestBuilder.create() now properly returns a new TestBuilder object instead of the singleton.
  • The useNumbers(), noHeader(), and noEnding() accessors will now properly assign a non-null value passed to them.
  • The arrays returned from summary() and details() now have the appropriate structures.
  • diag() now always properly adds a # character after newlines.
  • Added output(), failureOutput(), todoOutput(), warnOutput(), and endOutput() to TestBuilder to set up function reference to which to send output for various purposes. The first three each default to document.write, while warnOutput() defaults to window.alert and endOutout() defaults to the appendData function of a text element inside an element with the ID test or, failing that, window.write.
  • todo() and todoSkip() now properly add # after all newlines in their messages.
  • Fixed line ending escapes in diagnostics to be platform-independent. Bug reported by Marshall Roch.
  • Ported about a third of the tests from Test::Simple (which is how I caught most of the above issues). The remaining test from Test::Simple will be ported for the next release.

Many thanks to Marshall Roch for help debugging issues in IE.

Now, there is one outstanding issue I'd like to address before I would consider this production ready (aside from porting all the remaining tests from Test::Simple): how to harness the output. Harnessing breaks down into a number of issues:

How to run all tests in a single window. I might be able to write a build script that builds a single HTML file that includes all the other HTML files in iframes or some such. But then will each run in its own space without stomping on the others? And how would the harness pull in the results of each? It might be able to go into each of its children and grab the results from the TestBuilder objects…

More Feedback/advice/insults welcome!

Backtalk

Bill N1VUX wrote:

Purpose?

Since you didn't reply to comments on use.perl.org posting ... I'll repost my comment here.

This looks potentially useful, but I'm unsure for what.

Since Perl Test::Simple/Test::Builder is generally considered a Unit Testing framework (although it can be (ab)used as a Integration-Regression engine as well), and JavaScript (or ECMA Script) runs in a Browser that is usually deeply connected, I'm missing a contextual leap here.

I could really use a link to a web page describing the purpose and scope of the TestSimple JavaScript port. All the posts on Just A Theory and use Perl are Implementor's Doc, change-lists of what's implemented/fixed from your point of view. If there's a Project Homepage, it's not linked.

  • Is the point to integration test the whole distributed front-ends of applications from the (EcmaScript compliant) browser?
  • Or to unit test the client-side java-script as an entity, mocking the server??
  • Or is the point to Unit test JavaScript functions in the browser in vitro, mocking everything outside the current function?
  • Or is this for Unit Testing of the Presentation Layer on the server from the Brtowser? (If so, how can a JavaScript arrange to Mock the Model layer?)
  • Or is it more likely for driving Integration Testing from the browser with the scripting simplicity we've come to love, without resorting to OLE-stuffing the browser from Perl?

Digging into the TAR file (which I normally wouldn't do before peaking at the web copy of the POD2HTML's) I think I understand it's for unit-testing JavaScript classes, which I hadn't even considered. (JavaScript has classes that fancy? *shudder* no wonder pages don't work between browser versions.) I hope I don't need to do that.

How much of the other items above could I do with it, if any?

-- Bill

Theory wrote:

Re: Purpose?

Bill,

I thought that your questions were important enough that I wrote a separate post to address them.

—Theory

Bob Ippolito wrote:

bugs...

This is pretty cool, but
  • counting the number of tests is really annoying.. you really think that's a good idea?
  • for (var i in someArray) is not correct because if you extend the array prototype then you'll start seeing non-integer things... You should use the traditional for (var i = 0; i < someArray.length; i++)

Theory wrote:

Re: bugs...

Thanks for your comments, Bob. Although I will not be changing the Array class prototype, consumers of these modules might, so I'll take a look at the code to ensure that I always use for to iterate over an array. I just liked the for (var i in someArray) approach because it's easier to read (I am, afterall, JAPH).

As for the number of tests, this is actually a frequently asked question about TAP. Andy gets this question all the time. So I asked him for the standard answer, and here it is:

The correct number of tests is a test in itself. The number of tests also makes sure that nothing happened in the middle.

It's just funny to me that people complain that they have to be careful about how many tests they have. You mean I have to tell the machine how many tests so that it can watch my back? You WANT the machine to watch your back.

Anyway, this question comes up often enough that I'm going to recommend to Perl.com that they have Andy write an article about this.

And if none of this convinces you, then just use plan("no_plan"); and be done with it.

—Theory

Bob Ippolito wrote:

Re: bugs...

Yeah, I prefer the nicer syntax also, but it's not valid syntax for what you mean for it to do :)

My biggest problem with counting the number of tests is that the test count is all the way at the top of the script, and usually I'm working at the bottom of the script, so it's not very convenient. If you were able to do "test groups" instead, where you can say:

plan('tests.domFunctions', 4);
// 4 tests here
plan('tests.arrayFunctions', 8);
// 8 tests here...

it would also make sense to wrap the tests in a function like this:

function test_runner(tests) {
    try {
        tests();
     } catch (err) {
        // pretty print the keys in the exception
     }
}

test_runner(function () {
    // my tests here
});

This would really mitigate the need for counting the number of tests, because if your tests don't run until completion due to an exception, then you'll know about it.

Also, you could simply have a test terminator at the bottom, which signals that you've finished the tests: i.e. allOk();

Alternatively you could simply say that the test_runner function needs to return true at the end to signal that the tests are complete.

Theory wrote:

Re: bugs...

Yeah, I hear you about the top-of-the-script thing. I know developers who, for this reason, use plan("no_plan"); while writing a test script, and then change it to plan("tests", num); when they're done.

For larger projects, I agree that grouping things by functions (or even classes!) would be useful. Adrian has hinted that something like this might be do-able, but it's not on my personal to do list. I need to get a harness written next.

—Theory