how to unit test google apps scripts? - unit-testing

I'm trying to get set up with unit tests for google app scripts, and I found two projects:
https://code.google.com/p/gas-unit/
https://code.google.com/p/gasunit/
So I'm confused which to use :-)
I just had a go with the unhyphenated gasunit, which seems to expect that the script is embedded in a spreadsheet, which I am a little unclear on how to do ... and the scripts I want to test are web based scripts rather than spreadsheet ones
I had more luck testing the hyphenated gas-unit, which managed to send me both an email output of the test and generate a results page in my google site:
https://sites.google.com/site/testappscript2/TestResults
so I'm going to with gas-unit for the moment, but I'd really like to see some official testing framework incorporated by Google. In particular I'd like to find some way to get these scripts to be run with some frequency to send me the results. Also I'd love to get some BDD going; see my other posts:
How to get Cucumber/Capybara/Mechanize to work against external non-rails site
how to use capybara has_text
Come on Google, you famously have "Testing Rocks, Debugging Sucks" in all your bathrooms? How about better testing support for Google Apps Scripts?

You can try out QUnit for Google Apps Script. It is a patch for QUnit turned into a Google Apps Script library with API docs.
All you need is a script project that imports a QUnit library (for example the one with the project key MxL38OxqIK-B73jyDTvCe-OBao7QLBR4j) and has a doGet function that configures QUnit using URL parameters and optionally also with your own settings, loads a function that runs your tests, and finally returns QUnit.getHtml(). Here is an example:
function doGet( e ) {
QUnit.urlParams( e.parameter );
QUnit.config({ title: "Unit tests for my project" });
QUnit.load( myTests );
return QUnit.getHtml();
};
// Imports the following functions:
// ok, equal, notEqual, deepEqual, notDeepEqual, strictEqual,
// notStrictEqual, throws, module, test, asyncTest, expect
QUnit.helpers(this);
function myTests() {
module("dummy module");
test("dummy test", 1, function() {
ok(true);
});
}
Then authorize the script, save a version of it, publish the script project ("Deploy as web app") and go to the test URL ("latest code") with your browser. Your tests will be run and results will be displayed via HtmlService. You can single-click on them to see their assertions, but as of writing this, you will probably not be able to do so in Firefox 20 and 21 due to Caja issue 1688.

I just wrote another testing framework named GasT for my google spreadsheet add-on development & testing.
GasT is a TAP-compliant testing framework for Google Apps Script. It provides a simple way to verify that the GAS programs you write behave as expected. https://github.com/huan/gast
My goal is to get a simple tap tool like tape(for javascript) or bats(for bash). the test suite format is quite clear:
var gastLibUrl = 'https://raw.githubusercontent.com/zixia/gast/master/src/gas-tap-lib.js'
eval(UrlFetchApp.fetch(gastLibUrl).getContentText())
var test = GasTap.setPrintDriver('Logger')
function gast() {
test('do calculation right', function (t) {
var i = 3 + 4
t.equal(i, 7, 'I can calc 3 + 4 = 7')
})
test('Spreadsheet exist', function (t) {
var ss = SpreadsheetApp.openById('1TBJpvlW3WWney4rk1yW5N9bAP8dOMkWxI97dOtco-fc')
t.ok(ss, 'I can open spreadsheet')
})
test.finish()
}
Hope someone will like it. :)
there's a online version, you can go to have a look on it here: https://docs.google.com/spreadsheets/d/19M2DY3hunU6tDQFX5buJmZ_f3E8VFmlqAtodyC-J8Ag/edit#gid=0&vpid=A1

The clasp tool provides the ability to develop and deploy Apps Script projects locally from the command-line.
From the clasp repo:
npm install -g #google/clasp
enable Apps Script API: https://script.google.com/home/usersettings
Develop locally and use the clasp tool to deploy.
Edit the node-google-apps-script project has been deprecated in favor of clasp
There is the node-google-apps-script package to allow using standard JavaScript packages and automated testing tooling.
npm install -g node-google-apps-script.
Go through the authorization steps to provide client secrets to allow uploading and importing Apps Script projects.
Use gulp or grunt or whatever you use for test running normal JavaScript projects.
There is an official Google sample available that uses this workflow.
See Google Apps Developer Blog post announcement for more details.
Once the files are downloaded, convert them to TypeScript by renaming them to end with .ts instead of .js. Once they are TypeScript, ava can be used to test them. Converting them to TypeScript also lets one use ES6 language features.

I created gas-unit (https://code.google.com/p/gas-unit/) and have spent a bit of time over the last few days tidying up the examples and adding a HTML test runner.
I have been using it myself for some spreadsheet manipulation I've been doing with reasonable success. I've also been using Jasmine for non-GAS client side js work and have really enjoyed that. I miss the ability in gas-unit to easily create spys and I favour the BDD style of specification writing.
gas-unit has been a great learning exercise for me and it does work although there may be undiscovered issues with scope and closure - this is my first significant js exercise outside of DOM manipulation.
I think the future for testing in GAS has to be with a port of QUnit (as Adam suggests) or Jasmine. I had a quick look at what it would take to port Jasmine but as yet have not been able to find the time to tackle it.

Check out QUnitGS2 - a new Apps Script library using the latest version of QUnit (v2.10.1).

Related

What's the best way to set up unit testing in dart with the new test library?

There are a lot of resources out there for unit testing in dart using the old unittest library, but I can't find much about the test library, which was just released at the end of last year.
In unittest you could call useHtmlConfiguration() or useHtmlEnhancedConfiguration() that would serve up test results on localhost:8081 or whatever port you used with pub serve. The new library doesn't seem to have that, or at least it's not well documented. So my first question is: Is there a good way to run unit tests in the browser by typing localhost:8081 like with the old library, or does everything have to be done from the terminal?
I'm able to run the tests with pub run test:test --pub-serve=8081 -p firefox, but I'm just wondering if anyone has some "best practices" with this library to share since it's so new.
The test package only prints progress and test results to the console. WebStorm/IntelliJ in the most recent version provide a GUI API for running the tests.
The readme https://pub.dartlang.org/packages/test is quite comprehensive about how to use the package.
I wouldn't say the new test package is so new anymore. I'm using it since more than a year AFAIR and almost all packages maintained by the Dart team and probably most others are already migrated to the new test package.

Need a recommendation to use a testing platform

We are working on billing system (java based module)for that we would like to have a testing framework. That testing framework should be able to adoptable for any type of billing scenarios(eg: utility bill payments, water/electricity/or any other type billing) Normally the billing entity have common attributes like customer name/usage/ etc..I would like to pick a suitable testing platform to test our billing module.
It can be opensource/licensed software.
Can anybody suggest such a framework/engine?
If you wanna go for open source tool, then I'd recommend Selenium Webdriver with TestNG Framework. You can get lot of documentation and help on web.
You can go for Cucumber for describing various test scenarios (and their dependencies).
These scenarios will be backed by jUnit for gluing the description to executable code. jUnit will typically be used to write low level tests as well (for use by developers).
Cucumber has the benefit of giving you reports and can serve well for discussion with users and their representatives.
I would suggest following based on your given little description about your need :
1 - For functionality testing and to make all your scenarios automate use Selenium WebDriver
2 -Then if you want to priorities your testes , want to run tests through XML , want to run multiple tests then you can use TestNG Framework
Above are totally open source tool and you will get real benefit of those by scripting. They allow you to do scripting using programming languages like Java , Python , ruby and a little more. You will get all details once you visit my given links in above 2 points.
According to your given requirements I think above 2 tools are enough to make everything automate for testing.

scriptcs hosting - Advantages over Roslyn

If I want to support scripting in my application, does scriptcs offer any particular advantages over just using the plain vanilla Roslyn script engine?
Unfortunately there's not much documentation on hosting scriptcs yet, but I'll try to give you a short summary.
Hosting scriptcs in your application provides several features that vanilla Roslyn doesn't:
Pluggable Engines
While scriptcs comes with the Roslyn and Mono engines by default, you can easily replace it with another engine, i.e. F#, LOLcode or even Brainfuck.
Pre-processing
scriptcs will process your scripts and extract things like references (#r) and load other scripts (#load). There was also recently introduced custom ILineProcessors which lets you hook into the pipeline for custom processing. An example processor could look like this:
public class GistLineProcessor : DirectiveLineProcessor
{
protected string DirectiveName
{
return "gist";
}
protected override bool ProcessLine(IFileParser parser, FileParserContext context, string line)
{
var gistId = GetDirectiveArgument(line);
var gistContents = DownloadGistContents(gistId);
parser.ParseScript(gistContents, context);
return true;
}
private static string DownloadGistContents(string gistId)
{
// Download gist contents...
}
}
This processor will download a gist and execute it as part of your script, i.e. #gist 12345678.
NuGet integration
scriptcs has integration with NuGet. This means that if you want scripts to be able to use NuGet packages, just install them and they will automatically be loaded from within the packages folder.
Script packs
Script packs is scriptcs' way to remove boilerplate code. They can import namespaces, reference assemblies and expose functionality to scripts through Require<T>(). See Martin Doms' excellent blog post about building a scriptcs script pack. For a comprehensive list of available script packs, see Script packs master list.
REPL
As you probably know, scriptcs has a REPL. This can be reused in your own application to provide an interactive scripting session.
Debugging
Using the vanilla Roslyn script engine, you can't debug scripts very easily. scriptcs gives you the ability to debug scripts with source mapping through #line directives inserted during pre-processing.
I may have forgotten something, but these are the main points for choosing scriptcs over vanilla Roslyn. When it comes to the actual hosting, you have two options:
ScriptCs.Core
This is a super lightweight library that contains the core components of the scriptcs pipeline. However, it doesn't contain implementations for IScriptEngine (the engine that actually executes code) and IInstallationProvider (the component that installs packages, i.e. NuGet), these live in ScriptCs.Hosting and ScriptCs.Engine.Roslyn. If you use this library, you will have to do all the wire-up of the components yourself and you also need to provide an implementation for the engine and the package installer.
ScriptCs.Hosting
ScriptCs.Hosting is a convenience layer for hosting scriptcs in an application. It's used internally in scriptcs.exe and does all the wire-up of the components (via Autofac) for you. It contains the NuGet implementation for the package installer and has a dependency on ScriptCs.Engine.Roslyn by default. This is the preferred way to host scriptcs as it provides a ScriptServicesBuilder to easily replace scriptcs' internal services. See scriptcs' Program.cs for example usage.
This could sound confusing so if you have questions, please ask on JabbR, Github or on the Google Group.

How do I unit test UI via console

I know this has been asked many times but I want to be specific.
I use to use selenium. After googling it looks like I can run it via console and it gives me a bunch of text output but I rather not parse that and I want a pass/fail type of thing
Every once in a while I like to run all of my unit test on the UI not code. I don't want to submit a form with certain values, I want to see if I click this img does the dropbox beside it pop out and if i select a name will it be in the form which I'll then submit after running a few other things.
The reason I'd like this is certain features MUST ALWAYS be working so i'm ok with adjusting the unit test everytime I modify the UI for those feature. For the rest the unit test in code which checks business logic will be enough as those UIs are always changing or not very important.
It be nice if something can kickoff firefox and chrome (or webkit) but thats not required.
Like I said I'd like pass/fail, some kind of easy text to parse. Complex test is ok as I know regex but I don't want to figure out when one unit test ends or starts.
If you're using java/maven - I wrote a maven plugin for selenium that should do what you want:
https://github.com/willwarren/selenium-maven-plugin. You generate the tests in firefox + selenium, then save the files to a directory in your maven project.
If you're not using maven you can use the project that I built upon:
http://code.google.com/p/selenium4j
From the Readme:
We use selenium IDE to record our tests. We then saved the test cases into our project in the following fashion: (Note: currently the code from selenium4j only suports one level, so don't nest your folders)
./src/test/selenium
|-signin
|-LoginGoodPassword.html
|-LoginBadPassword.html
|-selenium4j.properties
We didn't save the test suites as maven takes care of finding your tests.
The selenium4j.properties contains setup information about:
# the web site being tested
webSite=http://yourwebapp:8080
# A comma separated values of the WebDrivers being used. Accepted drivers:
# HtmlUnitDriver, FirefoxDriver, ChromeDriver, InternetExplorerDriver
driver=FirefoxDriver
# How many times we want to iterate and test
loopCount=1
The selenium maven plugin, which is bound to the process-test-resources phase, then converts these html files into junit 4 tests in your src/test/java folder.
So you end up with:
./src/test/java
|-signin
|-firefox
|-LoginGoodPasswordTest.java
|-LoginBadPasswordTest.java

How to unit test with jasmine and browserify?

Any best way to run the jasmine HTML reporter with browserify styled code? I also want to be able to run this headless with phantomjs, thus the need for the HTML reporter.
I've created a detailed example project which addresses the jasmine testing (and others) - see https://github.com/amitayd/grunt-browserify-jasmine-node-example. Discussion at my blog post
The approach in this aspect was to create a Browserify bundle for the main source code (where all the modules are exposed), and one for tests which relies on external for the main source code. Then tests can be run both in PhantomJS or a real browser.
I don't think there's a jasmine-browserify package yet, and it doesn't really match Browserify/NPM's way of doing things (avoid global exports).
For now, I just include /node_modules/jasmine-reporters/ext/jasmine.js and jasmine-html.js at the top of my <head>, and require all my specs in a top-level spec_entry.js that I then use as the entry point for a Browserify bundle that I put right afterwards in the <head>. (Note that if the entry point is not top-level, you'll have a bad time due to a long-lasting, gnarly bug in Browserify).
This plays nicely with jasmine-node as long as you don't assume the presence of a global document or window. However, you do have to remember to register your specs in that spec_entry.js, unless you want to hack Browserify to get it to crawl your directories for .spec.js files.
I'd be very interested in a more elegant solution, though, that would transparently work with jasmine-node and browserify.
If you use grunt-watchify, no need to create spec_entry.js. Just use require in your specs, and then bundle your specs with grunt-watchify:
watchify: {
test: {
src: './spec/**/*Spec.js',
dest: 'spec/spec-bundle.js'
}
},
jasmine: {
test: {
options: {
specs: 'spec/spec-bundle.js'
}
}
},
Then run your tests with
grunt.registerTask('test', ['watchify:test','jasmine:test']);
As all above answers are little outdated (of course it doesn't mean that they are not working any more etc.) I would like to point to https://github.com/nikku/karma-browserify this is a preprocessor for karma runner. It combines test files with all required dependencies. Such created browserify bundle is passed to karma which base on configuration runs it. Please be aware that you can choose any modern test framework (jasmin,mocha...) and browsers (phantom, chrome ..) Probably this is exactly what you need :)
You may also want to look into Karma. It really simple to setup and it will watch for changes and rerun your test. Check out this sample project that uses Karma to test a browserify/react project. You just need to add a few dependancies and create a karma.conf.js file.
https://github.com/TYRONEMICHAEL/react-component-boilerplate