How to create a simple unit tests library for Google Apps Script

I realy like Google Apps Script. I think it’s a powerfull tool for entreprises needs. But there is a major risk on build a complex application on Google Apps Script : Maintenability.
Indeed, Google Apps Script is basicly javascript and it is very easy to build ugly and bad test code with Javascript.
Refactoring is a good way to keep code clean. If you want to refactor with zen spirit, it is good thing to have unit tests on your code.
There is unit test library for Javascript like  google-js-test, developped by Google, but I would like something more integrated.
That’s why I start to developpe my own library : GASUnit.

Files organisation

I separate code in 3 files :

  • a file for the code to test
  • a file for the test code
  • a file for the library
As I want easy re-use the library, I don’t put the file in script editor but on another server. Here I use code.google.com. Then I just need to call the library from the test file.
Another advantage of this option, I didn’t need to copy/paste the library content in all project when I make a change.

Structure of a test file

My test file contains 4 important elements :
  • The library import
  • The tests method
  • The assertions
  • The run method
The standard eval function is use to dynamicly add the library code. My tests are group in one test class.
var gasunit = UrlFetchApp.fetch("http://gasunit.googlecode.com/svn/trunk/gasunit.js").getContentText();
eval(gasunit);
Test methods are automatically run when you run test on object userTest.
var gasunit = UrlFetchApp.fetch("http://gasunit.googlecode.com/svn/trunk/gasunit.js").getContentText();
eval(gasunit);

var userTest = {
  testIsAdult : function(){
    var user =  new User("Doe","John","19");
    assertTrue(user.isAdult());
  },
  testIsNotAdult : function(){
    var user =  new User("Doe","John","17");
    assertFalse(user.isAdult());
  },
  testRecordUser : function(){
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
    sheet.clear();
    var user =  new User("Doe","John","17");
    user.record(sheet);
    assertCellContentEqual(sheet, "A1","Doe");
  },
  testRecordUserColorLine : function(){
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
    sheet.clear();
    var user =  new User("Doe","John","17");
    user.record(sheet);
    assertCellColorEqual(sheet, "A1","#cccccc");
  }
};

function main(){  
  GASUnit.runTest(userTest);
}

I add at the end of the script a main function to declare tests to execute.

Test results

When you run the test, the library create a new sheet for output.

You can see the results on this capture :

Conclusion
GASUnit is very young and have some bugs to correct, but I think it’s very usefull.
You can even schedule tests every night like in an integration way.