tsgast
v1.0.71
Published
TSGasT is a TAP-compliant testing framework for Google Apps Script(GAS) in TypeScript. It provides a simple way to verify that the GAS programs you write behave as expected.
Downloads
32
Maintainers
Readme
GasT - Google Apps Script Testing-framework in TypeScript
GasT is a TAP-compatable testing framework for Google Apps Script (GAS). It provides an easy way to verify whether GAS programs you write is behaving as expected or not.
Github: https://github.com/zixia/gast – Original Author
Github: https://github.com/kevicnar/gast – TypeScript conversion
A GasT unit test file is a javascript which defines GAS unit testing cases. Behind the scenes, each GAS test case is simply a function that takes a description parameter, and outputs in TAP format.
/// <reference path="./node_modules/tsgast/index />"
if ((typeof GasTap)==='undefined') { // GasT Initialization. (only if not initialized yet.)
eval(UrlFetchApp.fetch('https://raw.githubusercontent.com/kevincar/gast/master/index.js').getContentText());
} // Class GasTap is ready for use now!
let tap: GasTap = new GasTap();
function gastTestRunner() {
tap.test('do calculation right', function (t: test) {
let i: number = 3 + 4;
t.equal(i, 7, 'calc 3 + 4 = 7 right');
});
tap.test('Spreadsheet exist', function (t: test) {
let url: string = 'https://docs.google.com/spreadsheets/d/1_KRAtoDz2Pdcj9IPZI007I_gMzRyfmXf7gicgxVwYJc/edit#gid=0';
let ss: GoogleAppsScript.Spreadsheet.Spreadsheet = SpreadsheetApp.openByUrl(url);
t.ok(ss, 'open spreadsheet successful');
});
tap.finish();
}
GasT is most useful when testing javascript in Google Apps Script environment. if you are running outside of GAS environment, there are other TAP testing frameworks available, such as TAPE - a tap-producing test harness for node and browsers.
Test cases consist of Google Apps Scripts.
About TAP
TAP is Test Anything Protocol, as understood by Perl 1.0's t/TEST on year 1988.
commit 840163baa12f7970131f7841c479bccf5be40ba9
Author: Larry Wall <[email protected]>
Date: Sat Jan 30 23:00:00 1988 +0000
Version 2 implemented in year 1996.
commit 4bce96efdcaa480e392138e10166c92c5fc5f22c
Author: Perl 5 Porters <[email protected]>
Date: Fri Feb 2 18:52:27 1996 -0800
More TAP History: http://testanything.org/history.html
Today, TAP is widely supported as a unit testing framework by test harness and automated test framework, in almost all languages. TAP has Producers in: Ada, Arc (Lisp Dialect), C / C++, MyTAP (for MySQL), Common Lisp, Erlang, Limbo (OS Inferno), Forth, Go, Haskell, Java, Javascript, Lua, MATLAB, OCaml, Pascal, Perl, PostgreSQL, Prolog, Python, Ruby, PHP, PL/SQL, SH / Shell Script, DB2 SQL PL, Test and developer tools, Web services etc.
TAP Specification: http://testanything.org/tap-specification.html
TAP Specification 13: http://testanything.org/tap-version-13-specification.html
Writing tests
There's a very simple example at https://github.com/zixia/gast/blob/master/src/gas-tests.js, which is the test suite of GasT itself.
test(msg, cb)
: Create sub test
Create a new test with a description. cb(t) fires with the new test object t once all preceeding tests have finished.
test('I am a test', function (t) {
t.ok(true, 'true is ok')
})
t.ok(value, msg)
Assert that value
is truthy with an optional description message msg
.
t.notOk(value, msg)
Assert that value
is falsy with an optional description message msg
.
t.equal(actual, expected, msg)
Assert that actual == expected
with an optional description msg
.
t.notEqual(actual, expected, msg)
Assert that actual != expected
with an optional description msg
.
t.deepEqual(actual, expected, msg)
Assert that actual
and expected
have the same structure and nested values with loose comparisons (==) on leaf nodes and an optional description message
t.notDeepEqual(actual, expected, msg)
Assert that actual
and expected
do not have the same structure and nested values with loose comparisons (==) on leaf nodes and an optional description msg.
t.throws(fn, msg)
Assert that function call fn()
throws an exception.
t.notThrow(fn, msg)
Assert that function call fn()
does not throw an exception.
t.pass(msg)
Generate a passing assertion with a message msg
.
t.fail(msg)
Generate a failing assertion with a message msg
.
t.skip
: Easily skip tests
Tests can be skipped by using the t.skip function at the point in a test you wish to skip.
test('A test I do not want to execute for now', function (t) {
t.skip()
var ret = foo()
t.ok(ret)
})
Optionally, you may include a reason for skipping:
test('A test I do not want to execute for now', function (t) {
t.skip('This function will return true soon, but not now')
var ret = foo()
t.ok(ret)
})
Or you can skip conditionally:
test('A test which should run', function (t) {
if (foo != bar) {
t.skip('foo is not bar')
}
var ret = foo()
t.ok(ret)
})
t.end
: Prints a total line to log output. For an example "3 tests, 0 failures"
Total counts of the tests can be printed a total line after a test or after all.
Aliases: final
Logs
[17-04-13 17:04:15:788 MSK] TAP version GasTap v0.2.0(BUGGY)
[17-04-13 17:04:16:381 MSK] ok 1 - ALL FINE! - getBase()
[17-04-13 17:04:16:557 MSK] ok 2 - - getActiveData()
[17-04-13 17:04:16:562 MSK] 1..2
[17-04-13 17:04:16:568 MSK] 2 tests, 0 failures <= the end() result
[17-04-13 17:04:19:820 MSK] ok 3 - - getDestination
[17-04-13 17:04:19:826 MSK] 1..3
[17-04-13 17:04:19:831 MSK] 3 tests, 0 failures <= the end() result
t.totalFailed
, t.totalSucceed
, t.totalSkipped
: Checking test results
Totals of failed, succeed and skipped test can be checked programaticaly. You will find this usefull if you wish to throw an exception in case of test failures.
test.finish()
if (test.totalFailed()>0) {
throw "Some test(s) failed!"
}
Running tests
To run your tests, open google apps script editor, create a script file named Tests.gs, paste tests of GasT into it, then click Run in menu, select function gastTestRunner
. After click, you will get a message "Running function gast...". Wait until the message disapears, then click View in menu, select Logs. You will see the output like the following snapshot.
If GasT uses the default printDriver Logger, it will print message in Google Apps Script Logger.log(). If GasT is not run inside google apps script, in other words, if you run it from a continuous integration system, you can use other printDriver like ConsoleLog
(currenlty not supported), it will output in machine-parsable TAP format.
GasT always uses TAP format output(it's buggy now, more fix needed).
TAP version GasT v0.1.0(BUGGY)
ok 1 - true is ok - TAP ok
ok 2 - false is not ok - TAP ok
ok 3 - true equal true - TAP equal
ok 4 - true not equal false - TAP equal
ok 5 - exception throwed - TAP exception
ok 6 - no exception found - TAP exception
ok 7 - unknown driver throws exception - TAP setPrintDriver
ok 8 - skipped # SKIP - TAP skip
ok 9 - passed # PASS - TAP pass
not ok 10 - this should fail # FAIL - TAP fail
1..10
10 tests, 1 failures, 1 skipped
Screen Snapshoot
An online version of google spreadsheet bounded with GasT google apps scripts can be found here:
- Spreadsheet - https://docs.google.com/spreadsheets/d/19M2DY3hunU6tDQFX5buJmZ_f3E8VFmlqAtodyC-J8Ag/edit#gid=323390886
- Script editor - https://script.google.com/a/zixia.net/macros/d/Mta4oea1VMIugfSGRo4QrAnKRT9d30hqB/edit?uiv=2&mid=ACjPJvGt4gnXjJwXnToB0jIMEbSvqKUF6vH-uq-m59SqnjXqTQ03NDn_khlNE6ha_mPnrOAYEnyFk80nHYmt_hppO3AgDkO_vVLrYJXzcPPagwRromd0znfLreNFAu4p0rYTC-Jlo-sAKOM
Using GasT in Google Apps Script
There's two ways to load GasT library into your code:
- Use eval below(Recommended because it's the easist way to use GasT)
Zero setup, paste and run. - GasT project key:
ME7pXzfKF5_60_TNOSJ2ylCqMEWMB0UzS
Input it into script editor -> Resources -> Libraries... -> Find a Library, then click Select.
Install GasT is very easy: simply copy/paste the following javascript code to your Code.gs file, then you are ready to use GasT.
if ((typeof GasTap)==='undefined') { // GasT Initialization. (only if not initialized yet.)
eval(UrlFetchApp.fetch('https://raw.githubusercontent.com/zixia/gast/master/src/gas-tap-lib.js').getContentText())
} // Class GasTap is ready for use now!
var test = new GasTap()
Also you can decide to use the best practices from developers.google.com. By caching data, you can reduce the number of times or frequency with which you have to fetch the data.
if ((typeof GasTap)==='undefined') { // GasT Initialization. (only if not initialized yet.)
var cs = CacheService.getScriptCache().get('gast');
if(!cs){
cs = UrlFetchApp.fetch('https://raw.githubusercontent.com/zixia/gast/master/src/gas-tap-lib.js').getContentText();
CacheService.getScriptCache().put('gast', cs, 21600);
}
eval(cs);
} // Class GasTap is ready for use now!
var test = new GasTap()
To use GasT, we need a wraper function(to run inside Script Editor). The following code is a simple template, you can add more test cases in the gastTestRunner() function, then run gastTestRunner() to see the test results.
function gastTestRunner() {
test('calculation', function (t) {
var i = 3 + 4
t.equal(i, 7, 'calc 3 + 4 = 7 right')
})
test('number convertion', function (t) {
var i = parseInt('0e0', 16)
t.equal(i, 224, 'parseInt')
})
test.finish()
}
Remember to keep test.finish()
at the end of function, because it needs to output the summary of all test results.
How to print TAP results other than using Logger.log
GasTap uses Google Apps Script's standard log function Logger.log as default output.
If you want to output results to a Spreadsheet or other destinations, it's very easy to use the printer
option to inject an output function.
var test = new GasTap({
printer: function (msg) { Logger.log(msg) }
})
Above is the default setting of GasTap. You can modify the printer function based on your requirement, as long as the function accepts the same parameter.
The following example sets GasTap to output test tap results to a google spreadsheet using a log library writen by me: GasL (GasL is a unix syslog like logging framework for Google Apps Script(GAS). It provides easy way for the GAS programs to log messages to Spreadsheet, LogEntries, RESTFUL API and Logger of GAS.)
/**
*
* Load Libraries
*
*/
if ((typeof GasTap)==='undefined') { // GasT Initialization. (only if not initialized yet.)
eval(UrlFetchApp.fetch('https://raw.githubusercontent.com/zixia/gast/master/src/gas-tap-lib.js').getContentText())
} // Class GasTap is ready for use now!
if ((typeof GasLog)==='undefined') { // GasL Initialization. (only if not initialized yet.)
eval(UrlFetchApp.fetch('https://raw.githubusercontent.com/zixia/gasl/master/src/gas-log-lib.js').getContentText())
} // Class GasLog is ready for use now!
/**
*
* Create a log function that writes to google spreadsheet
*
*/
var sheetPrinter = new GasLog.Printer.Spreadsheet({
url: 'https://docs.google.com/spreadsheets/d/1_KRAtoDz2Pdcj9IPZI007I_gMzRyfmXf7gicgxVwYJc/edit#gid=0'
, sheetName: 'GasTap'
})
var log = new GasLog({
printer: sheetPrinter
, ident: 'GasT'
})
/**
*
* use the log function above to output test TAP results to Google Spreadsheet:
* https://docs.google.com/spreadsheets/d/1_KRAtoDz2Pdcj9IPZI007I_gMzRyfmXf7gicgxVwYJc/edit#gid=0
*
*/
var test = new GasTap({
logger: log
})
Support
The GasT source code repository is hosted on GitHub. There you can file bugs on the issue tracker or submit tested pull requests for review. ( https://github.com/zixia/gast/issues )
For real-world examples from open-source projects using GasT, see Projects Using TasT on the wiki. ( https://github.com/zixia/gast/wiki )
Version history
v0.3.0 (Feb 26, 2016)
- Published with project key
ME7pXzfKF5_60_TNOSJ2ylCqMEWMB0UzS
(thanks @brucemcpherson for suggestion)
v0.2.0 (December 14, 2015)
- Support output to spreadsheet (LogEnteries, etc). powered by GasLog modle.
Use v0.2.0 in GAS
/**
*
* GasT v0.2.0 Initialization. (only if not initialized yet.)
* https://github.com/zixia/gast
*
*/
if ((typeof GasTap)==='undefined') {
eval(UrlFetchApp.fetch('https://raw.githubusercontent.com/zixia/gast/v0.2.0/src/gas-tap-lib.js').getContentText())
} // Class GasTap is ready for use now!
v0.1.0 (December 2, 2015)
- Initial public release.
© 2015 Zhuohuan LI. GasT is released under an MIT-style license; see LICENSE for details.