LoginSignup
11
4

More than 1 year has passed since last update.

Docker+Clasp+Jest+GitHub ActionsでモリモリGAS開発

Last updated at Posted at 2021-12-03

本記事は、サムザップ Advent Calendar 2021 の12/4の記事です。

はじめに

はじめまして、サムザップの北島です。

突然ですが、Google Apps Script(以降、GAS)で色々している皆さん!
GASは便利ですが、ブラウザのエディター上で開発するのはちょっと大変ですよね。
そこで、今回は Docker + Clasp で開発環境を作りつつ、さらに Jest + GitHub Actions でテストもしてしまえ!という内容です。

というわけで、Docker、Clasp、Jest、GitHub Actionsと、4つについてそれぞれ書いていきます。
が、詳しく書いていくとかなり長くなってしまうため、今回はポイントを絞って簡潔にという感じにしております、ご了承ください。

開発環境

まず、今回作る開発環境の構成は以下になります。

| - gas
|    | - .github
|    |    | - workflows
|    |    |    | - ci.yml
|    | - .docker
|    |    | - Dockerfile
|    |    | - docker-compose.yml
|    | - src
|    |    | - package.json
|    |    | - babel.config.js
|    |    | - node_modules
|    |    | - hoge
|    |    |    | - .clasp.json
|    |    |    | - .claspignore.json
|    |    |    | - appsscript.json
|    |    |    | - hoge.ts
|    |    |    | - __test__
|    |    |    |    | - hoge.test.ts

Docker

では、Docker環境の構築についてです。
Dockerをインストールした状態で、以下のファイルを用意してください。
なお、後に出てくる Clasp、Jest の設定もここでしてしまいます。

.docker/Dockerfile

FROM node:16.4.1
RUN npm i @google/clasp -g

.docker/docker-compose.yml

version: '3'
services:
  gas:
    build: .
    tty: true
    container_name: 'gas-container'
    volumes:
      - ../src/:/opt/
    working_dir: /opt

src/package.json

{
  "dependencies": {
    "@google/clasp": "^2.4.1",
    "google-spreadsheet": "^3.1.15",
    "npm": "^7.20.6"
  },
  "devDependencies": {
    "@babel/cli": "^7.14.8",
    "@babel/core": "^7.15.0",
    "@babel/plugin-transform-modules-commonjs": "^7.15.0",
    "@babel/preset-env": "^7.15.0",
    "jest": "^27.0.6",
    "jest-junit": "^12.2.0"
  },
  "jest": {
    "globals": {
      "SpreadsheetApp": {}
    }
  }
}

src/babel.config.js

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current',
        },
      }
    ]
  ],
  plugins: [
    '@babel/plugin-transform-modules-commonjs',
  ]
}

用意ができたら、以下のコマンドで環境を立ち上げることができます。

初回のみ

$ cd .docker

$ docker-compose build --no-cache
$ docker-compose up -d

$ docker-compose ps

  ※以下があることを確認
  Name        Command              State  Ports
  -----------------------------------------------------
  gas-container   docker-entrypoint.sh node   Up

(停止するときは以下)
$ docker-compose down

初回以降

$ cd .docker
$ docker-compose up -d

(停止するときは以下)
$ docker-compose down

Clasp

続いて、Claspについてです。

Claspは、Google が提供するGASをローカルで管理できるようになるツールになります。
素直にGASの開発を行うと、ブラウザ上のエディターにコードを書くことになりますが、Claspを使うとローカルで書いたものを clasp push で簡単に反映できるようになります。

上記のDocker環境を立ち上げた状態で以下を実行します。

$ docker-compose exec gas bash

$ npx clasp login --no-localhost

  ※URLが表示されるのでブラウザでアクセスしGoogleアカウントでログイン
  ※codeが表示されるのでコピペ

これにより .docker/.clasprc.json が作成され、以降はGoogleへのログインが不要になります。
次に .clasp.json を用意します。

src/hoge/.clasp.json

{
  "scriptId":"【管理したいGASのID】"
}

Claspで管理したいGASは予め作成しておいてください。
これで以下のコマンドが実行可能になります。

$ npx clasp pull

  GASに反映されているコードをローカルに持ってきます

$ npx clasp open

  GASをブラウザで開きます

$ npx clasp push

  ローカルのコードをGASに反映します

ローカルでの開発が可能になりましたね!

Jest

続いて、Jestです。
Jestのインストールは以下でできます。

$ docker-compose exec ikusa-gas bash
$ npm install --save-dev jest

Jestを使うことで、GASのテストコードを書くことができます。
コードは __test__ 配下に置くか、ファイル名を hoge.test.ts とします。

テストするコードのサンプル(src/hoge/hoge.ts)

/*
 * 足し算
 */
function plus(a, b) {
  return add(a, b);
}

/*
 * スプレットシートの範囲を指定して取得、配列で返す
 */
function getSheetAsArray(ssUrl, ssName, startRow, endRow, startColumn, endColumn) {
  var sheet = SpreadsheetApp.openByUrl(ssUrl+"\/").getSheetByName(ssName);
  var result  = sheet.getRange(startRow, startColumn, endRow-startRow+1, endColumn-startColumns+1).getValues();

  return result;
}

テストコードのサンプル(src/hoge/__test__/hoge.test.ts)

import {plus, getSheetAsArray} from '../hoge.ts';

// モックの例
SpreadsheetApp.openByUrl = jest.fn(() => ({
  getSheetByName: jest.fn(() => (
    {
      getRange: jest.fn(() => (
        {
          getValues: jest.fn(() => [
            ["HEAD1", "HEAD2", "HEAD3"],
            ["A1", "B1", "C1"],
            ["A2", "B2", "C2"],
          ]),
        }
      )),
    }
  )),
}));

// テストの例
describe('テスト', () => {

  it('plus', () => {
    var result = plus(2, 3);
    expect(result).toEqual(5);
  });

  it('# getSheetAsArray', () => {
    var output = getSheetAsArray();
    expect(output[0][0]).toBe("HEAD1");
    expect(output[0][1]).toBe("HEAD2");
    expect(output[0][2]).toBe("HEAD3");
    expect(output[1][0]).toBe("A1");
    expect(output[1][1]).toBe("B1");
    expect(output[1][2]).toBe("C1");
    expect(output[2][0]).toBe("A2");
    expect(output[2][1]).toBe("B2");
    expect(output[2][2]).toBe("C2");
  });

});

こんな感じで簡単にテストが書けます。
GAS開発の場合、スプレットシートを使うことが多いと思います。
スプレットシートを操作するような関数は、上記のようにモック化すると良いと思います。

テストを実行する方法は以下のとおりです。

すべてのテストを実行する場合
  $ docker-compose exec gas npx jest

管理するGASが複数になり、特定のテストだけを実行する場合
例)src/hoge2 配下のテストを実行する場合
  $ docker-compose exec gas npx jest --verbose hoge2

なお、テストコードはGASに上げる必要はないので .claspignore を設定すると良いです。

src/hoge/.claspignore

__test__/*

GitHub Actions

最後に、GitHub Actionsについてです。
上記ではテストを手動で実行しましたが、GitHub Actionsを使うことで自動で実行することができます。
(GASのコードをGitHubでバージョン管理している前提です。)
masterブランチへのプルリクが作成されたタイミングでテストを実行したい場合を例として載せておきます。

.github/workflows/ci.yml

name: CI

on:
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - name: git clone
        uses: actions/checkout@v1
      - name: Instal node
        uses: actions/setup-node@v1
        with:
          node-version: '16.4.1'
      - name: Install npm
        run: npm install -g npm@7.18.1
      - name: Install jest
        run: npm install --save-dev jest
        working-directory: ./src
      - name: Install babel
        run: npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/plugin-transform-modules-commonjs
        working-directory: ./src
      - name: Run test
        run: npx jest
        working-directory: ./src

まとめ

というわけで、今回は Docker + Clasp + Jest + GitHub Actions でGAS開発をモリモリにする方法を紹介しました。
日頃、GASで開発をしている皆さんの参考になれば嬉しいです。

以上、サムザップ Advent Calendar 2021 の12/4の記事でした。
明日は @fuzy さんの記事です、お楽しみに!

11
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
4