Art of the Smart

Testing & Testability In Apps Script

Categories: [coding], [ob2ss]
Tags: [apps-script], [code], [spreadsheets]

Apps Script testability is a tricky subject and a lot depends on how you've structured your project. I wanted to write a quick blog post to organize my thoughts on the subject and maybe help others in the same situation.

When you're writing Google Apps Script, especially very large projects or libraries, you're going to want some kind of testing. Trouble is, there's a tradeoff between ease of development and ease of testing in this regard.

I'm not an engineer, so take all of this with a grain of salt. These're just my feelings on the subject.

Minimize and localize your calls to the global services. What I mean by this is that you'll want to keep calls to stuff like SpreadsheetApp and DocumentApp isolated from the rest of your code where possible. These're super duper hard to test, even if you're using end-to-end testing systems like my QUnit port. Calls are expensive and testing interactions means you have to modify real documents and spreadsheets and read outcomes to determine how things went. Unless you want to build mocks. Yuck.

Use offline, local testing if possible. I've used Jest in recent projects and found it really useful. For classes and methods that don't interact with global services, you can use testing frameworks like Jest, Karma, Jasmine, etc. It's super fast, you can use features like watch to speed up development. It's lovely. Where you can't have that, opt for the end-to-end stuff described above and/or more complex solutions like below.

Compilation makes testing twice as hard. Using webpack to manage really large projects has serious benefits. Easier to wrangle code complexity, you can include off-platform libraries, use modules, use Typescript more effectively, and whole bunch more. The downside? It hides/obfuscates/prunes code that you might need to test, and that goes double in a Library where you're closely managing exposed APIs. For example, classes cannot be instantiated outside the library so, in a sense, you can only perform end-to-end tests. Good luck if something doesn't work perfectly right away.

To deal with this, consider having multiple .clasp.json files and juggling them with npm commands like in this thread on Github.