GASを書いていて、テストを書きたくなる時って結構ありませんか?
ただ、なかなか手をつけることができずにテストを書かずにおいてしまい罪悪感が積もりに積もったので、ついにテストを書きました 🎉🍾✨
そのことについてまとめます❕
(TypeScriptはまだまだ勉強中でエセなのでご了承ください🙇)
もくじ
準備🎒
npm install -D clasp @types/google-apps-script
$ npm install -D clasp @types/google-apps-script
tsconfig.jsonを追加
$ tsc -init
//tsconfig.json { "compilerOptions": { "lib": ["esnext"], "experimentalDecorators": true } }
npx clasp create --type standalone --rootDir src
$ npx clasp create --type standalone --rootDir src // src/appsscript.json と .clasp.json が生成される // src/appsscript.json { "timeZone": "America/New_York", "dependencies": { }, "exceptionLogging": "STACKDRIVER", "runtimeVersion": "V8" } // .clasp.json {"scriptId":"xxx","rootDir":"src"}
テストコードはclasp pushする必要がないためsrc/以下にappsscript.jsonを生成しました。
//構成 . ├── README.md ├── node_modules/ │ ├── src ←clasp pushの対象ルートディレクトリ │ ├── _utils.ts │ ├── appsscript.json │ └── code.ts │ ├── tests ←テストコードのディレクトリ(clasp pushしない) │ ├── _utils.test.ts │ ├── date-mock.ts │ └── gmail-message-mock.ts │ ├── jest.config.js ├── package.json ├── tsconfig.json └── .clasp.json
npm install -D jest "@types/jest" ts-jest typescript
$ npm install -D jest "@types/jest" ts-jest typescript
jest.config.jsを追加
$ jest --init
参考: https://typescript-jp.gitbook.io/deep-dive/intro-1/jest#suteppu2jestwosuru
//jest.config.js module.exports = { "roots": [ "<rootDir>" ], "testMatch": [ "**/__tests__/**/*.+(ts|tsx|js)", "**/?(*.)+(spec|test).+(ts|tsx|js)" ], "transform": { "^.+\\.(ts|tsx)$": "ts-jest" }, }
tsconfig.jsonにesModuleInterop=trueを追加
以下のwarningがでたため、言われるがままに”esModuleInterop”: trueを追加しました。
ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`)
//tsconfig.json { "compilerOptions": { "lib": ["esnext"], "experimentalDecorators": true, + "esModuleInterop": true, //追加 } }
src/appsscript.jsonのtimeZoneを”Asia/Tokyo”に修正
//src/appsscript.json { - "timeZone": "America/New_York", + "timeZone": "Asia/Tokyo", ... }
npm test
でテスト実行できるようにする
//package.json { .... + "scripts": { + "test": "jest" + } }
テストを書く📊
GmailMessageのモックを作る
テストできるように、インターフェースGmailMessageを実装してモック(GmailMessageMock)を作成しました。
tests/gmail-message-mock.ts
import GmailMessage = GoogleAppsScript.Gmail.GmailMessage; export class GmailMessageMock implements GmailMessage { constructor( private body: string, ) { } getBody(): string { return this.body; } ... }
tests/_utils.test.ts
import { Utils } from "../src/_utils"; import { GmailMessageMock } from "./gmail-message-mock"; describe('Utils.createBodyMessage', () => { test('[body]xxxを生成できること', () => { const inputGmailMessage = new GmailMessageMock('テストメッセージです'); const util = new Utils(); const actual = util.createBodyMessage(inputGmailMessage); expect(actual).toBe('[body]テストメッセージです'); }) })
src/_utils.ts
export class Utils { public createBodyMessage(gmailMessage: GoogleAppsScript.Gmail.GmailMessage): string { return "[body]" + gmailMessage.getBody(); } }
ついに、テストできるようになりましたー🎉🎉🎉
$ npm test > test > jest PASS tests/_utils.test.ts Utils.createBodyMessage ✓ [body]xxxxを生成できること (2 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 2.657 s Ran all test suites.
メモ📝
– GASではimportができないので、読み込み順序をいい感じにするために先に読み込まれる必要があるファイルについては_hoge.ts
のようにアンダーバーから始まるファイル名にしました🚨
– clasp pushされるとcode.ts→code.gsに変換されます。
参考にした記事🙇
– https://developers.google.com/apps-script/guides/clasp
– https://kotamat.com/post/gas-testing/
最後に
詳細が気になる方は、https://github.com/kin29/line-notify-from-gmailにコミット履歴があるので参考にしてみてください。
(最初yarn使ってたのですが、npmだけでいけそうなので最後にyarn.lockを消したりしてます)