As well as defining a specification for representation, interaction with legacy systems, internationalisation we need a definite specification for dealing with these strange objects. For example is March 14 'before' March?, What is January 31 plus one month?
So we have a lengthy and detailed specification which of course we need to implement. So we're set to write a load of tests with expected results which was exactly how I started. Back in 2008 I was using Delphi/Pascal which was a slightly different workflow to the Javascript version but the test scripts were still valid.
Now write lots of lines for lots of tests and throw at some test runner. The runner is a web page that lists available scripts and gives some control over which lines to run. For example an issue might need a lot of instrumentation or debugging for a single line in isolation. Here is a simple method of automatically listing the available stript files.
The next evolutionary stage was to remove the hard-coded functions from the test runner code and create a number of js files which used a 'load me into a methods libary' function around the test method.
The problem of how to incorporate these files into the complete development package. This is what gulp is good for. As soon as a method file was changed gulp would notice and rebuild. This worked fine, but for any other tester they'd need to rebuild using the fiddly build infrastructure.
The example on the right shows that we've embedded some basic documentation which tells us how to make use of the method. (In case you think there's a lot of complexity involved, the test runner needed 10 lines to implement adding methods and producing a html table for reference. It's actually simpler than a large switch statement.)
The current system uses a similar file discovery process to that used for scripts. When initialising the test runner we look for js files in a designated methods directory and load them. eval() is ideal and not something to worry about in this context.
Example method file
It's actual javascript with replace, uglify, and concat being plug-ins loaded with require().
The basic usage is to run a whole script file and home in on the 'red' lines. A point to watch is you need a class of script line that will always get executed. Suppose line 10 changes a configuration setting and line 15 is the one you're looking at, then you still have to process the lines before 15 so that permanent state changes are executed.
Gulp file | Test console code |
var flagTestbedReload = function() {
require('fs').writeFile('tests/nonce.txt', new Date());
};
All we do is change a flag file when we've 'recompiled'. The browser checks every few seconds to see if it has changed, and if so saves any state to localStorage and reloads itself. On reload it will read the just saved state and it's like nothing has happened except now it's 100% up to date. |
// set the watch for server-side changes (during page ready)
__localNonce = undefined;
window.setInterval(TestNonce,5000);
function TestNonce(){
$.ajax({url:'nonce.txt',cache:false,timeout:1000,dataType:'text',
success : function(Data,S,X){
if(__localNonce){
if(__localNonce != Data){ // compare with previous
// save any current state in localStorage (not shown)
location.reload(true);}
}else{ __localNonce = Data;} // set first time
}});};
|
TODO Batch testing in node
TODO Trivia. (Colour bar)
TODO Other tools (Function ref.)
* file listing
* function reference prog
* interactive testing (browser)
* batch testing (node)
* trivia
colour bar