Skip to content

cjohansen.no

Stepping Through JsTestDriver Tests

Sometimes it's useful to split largish JsTestDriver test suites into smaller chunks for debugging, or for slower runs. Here's a quickie little script I wrote to do just that.

The Problem

JsTestDriver allows you to run a specific test case (or several) or all of them. The problem is that if you want to run only a few of your cases you need to name them all, which quickly becomes bothersome.

When would you want to run only parts of the test suite? Well, sometimes, largish test suites can totally stress out less capable browsers, like, oh say Internet Explorer 6. Running too many, or too complicated tests too quickly can cause IE to freak out in the most vile ways. Also, some kinds of test failures can cause IE (and other browsers) to behave badly.

The Solution

When weird problems like these occur, and it's not obvious why, I like to step through the tests, one file at a time, to locate the offending test(s). Rather than manually punching in the names of the test cases I wrote a simple Ruby script. It locates all test files, then extracts all test cases from them and runs the tests, one test case at a time.

Note that the following script uses my jstdutil gem, which provides the jstestdriver command.

#!/usr/bin/env ruby
#
# Sometimes massive failure can cause JsTestDriver to hang
# To debug those cases, it's easier to run test cases one by one
# to track which test case is causing trouble.
#
# This script also helps test less capable browsers such as IE6,
# which can get overwhelmed while trying to run too many tests too
# quickly.
#
def red(msg)
  "\033[31m#{msg}\033[39m"
end

def green(msg)
  "\033[32m#{msg}\033[39m"
end

def ok
  green("OK")
end

problems = []

print "Resetting"
`jstestdriver --reset`
print " - #{ok}\n"

(Dir.glob("test/**/*.js").collect do |test|
  File.read(test).scan(/estCase\("(.+)"/)
end).flatten.each do |testCase|
  print testCase
  `jstestdriver --tests #{testCase}` =~ /Fails: (\d+); Errors: (\d+)/

  if $1.to_i > 0 || $2.to_i > 0
    problems << testCase
    print " - " + red("#{$1} failures, #{$2} errors") + "\n"
  else
    print " - #{ok}\n"
  end
end

if problems.count > 0
  puts red("Some test cases had failures and/or errors")
  puts problems.join("\n")
else
  puts green("No problems")
end

Note that the script scans for "estCase". The reason for this is that sometimes I use JsTestDriver's TestCase function, and sometimes I use a custom testCase, which wraps the test case in a sinon.testCase call.

The following is an example run stepping through Sinon's tests:

Well, there you have it. Put the script in e.g. step-tests, make it executable, and run whenever you're having weird problems occurring.

Possibly related

2006 - 2012 Christian Johansen Creative Commons License