経緯
- 業務のJS(結構モダン)をTypeScript にしたい
- テストが全くないので、テストをまず作りたい
- テストフレームワークは流行ってるみたいなのでJestにしよう
- 前回(38日前)、Jest自体は TypeScript の単体テストで Jest 使おう - Qiita をやってみて、一応使えるようになった
- 今回は、実際の業務のコードを1つJest にしてみる
概要
- めちゃくちゃ詰まったポイントがあった
- 業務のコードの拡張子が .js だと、 「ES mocules の import を使いなさい」みたいなError がでたが、 .ts にしたら解消した
- Jest でテストコード(window.alertが文言指定で出るか) 自体は一瞬で書けた
かかった時間
- 5/22, 24 作戦考える (5日間開く)
- 5/28 Jest やりはじめる (~5/30)
- 6/1 import export のエラーに苦しみ始める
- (6/18 まで評価資料5月分の方をする)
- 6/19~6/25 そのエラーに取り組む (1日10~30分)
- 6/26 ~6/29 そのエラーを突破できたので、先を進める
- 6/30 ブログを書き始める
- つまり、2週間弱かな?
- このブログを書くのに 2022/07/05 1:43 まで 6日間、80分かかった
やったこと
- 業務のJSがあるので(いい感じにモジュール化されてる)、それについて https://qiita.com/okazuki/items/991a068892e946531612 (この前やったqiita)の通りやってけば、 test できそう
最終的にいい感じに通った時のコード
- Marumaru という機能があると思ってください
- npm t するとテストが通る (上のqiita 通りに組んだので)
marumaru.test.ts import zembu from "../src/marumaru"; beforeAll(() => { // window.alertをモックにする。Jestではモックにしないとエラーになる window.alert = jest.fn() }); test('test', () => { zembu.add_marumaru('hikisuu1', 'hikisuu2', 'hikisuu3'); expect(window.alert).toHaveBeenCalledWith('ログインしてね'); });
marumaru.ts import $ from "jquery"; import "jquery.cookie"; const add_marumaru = function (hikisuu1, hikisuu2, hikisuu3) { 略 alert('ログインしてね'); }; 略 export default { add_marumaru, add_kakukaku };
- …と、何の変哲もない(?) ES Modulesなコードだった
- しかし、 marumaru.ts ではなく marumaru.js にしてたため、長いこと import 周りで悩んだ
詰まる前編
- marumaru.test.ts に import Marumaru from "./src/marumaru"; とかいたら 問題タブに モジュール './src/marumaru' またはそれに対応する型宣言が見つかりません。と言われたのでts設定をゆるく仕様とおもった
- ↓もしたが、僕の場合効果がなかった
- 多分 TypeScript未対応のモジュールをimportするときのエラー対策 - Qiita を参考に、とりあえず //@ts-ignore をつけたら問題は消えた
- // をつけないといけないのかな? (js難しいポイント)
export のエラー文言が出る試行錯誤編
- npm t したら SyntaxError: Unexpected token 'export' で悩んでる 2022/06/01 0:38
- https://jestjs.io/docs/ecmascript-modules をよめばいいのかな 16m 2022/06/01 0:39
- JestをES6化してimport/exportを使う方法 もやってみた
cross-env編
- Windowsユーザーはcross-envを使うと良いらしい
- そもそもcross-envとはなんなのかを知るぞ2022/06/20 1:00
- Nuxtでcross-envを使い環境ごとに環境変数を分ける - Qiita
- env.development.js (開発環境用ファイル) とかを使うんだね
- 多分、この環境設定ファイルに、ESModulesを使うためのオプションを書くのだろう
- npm install --save cross-env
- なんでも npm にある
- うーん、cross-envの確認方法がほしい
- 内容的には↓に近そう(多分結果的には違った)
にっちも察知もいかないから0からやる編
- ↑↑↑のQiita 自体で練習はできたので、それから、少しずつ、やりたいコードに変えていけば、おかしくなったところがどこか気づける作戦
- tsconfig.json の "module": "commonjs", がだめそう 2022/06/21 22:54
- 最終的には此れで問題無かった 2022/07/04 2:43
- package.json の "type": "module", も 最終的には此れで問題なかった
- 2019.3 と、 かなり最近なんだなあ
// 近しいpackage.jsonのtypeがmoduleなので、このファイルはESMで読み込まれる import './sample/setup/init.js'; // ./node_modules/foo/package.jsonにはtypeが書いてないため、CJSで読み込まれる import 'foo';
とのことなので、 type: module だと、 eS modules になるのだろう ぜ ぜ - まぁ、おいおいわかっていくだろう
- 途中で読んだqiita
- 多分、最初にうっかり CommonJS形式を選んでしまったのだと思う
2022/06/21 23:07
- そうでもないかも
- ターミナルをvscodeで右に表示するとみやすいかも
- ターミナル? PowerShell のスクロール設定がわるい
- キーボードならたしかにこれ Ctrl + PageUp [Powershell]Powershellコンソールで1行ずつスクロールする – エンジニ屋
- スクロールの行数は他のソフトと共通で7ぎょうだった ただ、中割が ないのでPower11hell は特にみにくい(諦め) OR<IOOまぁ、→のスクロールバーをつかめばいい
- ターミナル? PowerShell のスクロール設定がわるい
まだまだ試行錯誤編
- なんか、いけそうな気もしてるたので、なかなか0からというか、上手くいったやつから寄せていかなくて苦労してる
- module.exports を export default { にもどしたら、おなじみの SyntaxError: Unexpected token 'export' がでた。
- 一度諦めてcommonJS形式にしたときの記録
- JSは同じことについて運種類も書き方があって難しい ユーザが必要な機能を次から次に実装していいた結果
- とはいえ、ややこしいだけで普通に習得していけるものなのだろうと思う 難しくて時間がかかるけど
- JSは同じことについて運種類も書き方があって難しい ユーザが必要な機能を次から次に実装していいた結果
- 一度諦めてcommonJS形式にしたときの記録
- やっぱり最初からやろうか。
- 最初から練習でうまくできたqiita をやったら そのまま npx tsc -init したら、かってに module:commonjs になった
- 最終的にもこれでうごいてた
- npx tsc -init
Created a new tsconfig.json with: TS target: es2016 module: commonjs strict: true esModuleInterop: true skipLibCheck: true forceConsistentCasingInFileNames: true
- "module": "es6", / Specify what module code is generated. / にしてみた 2022/06/22 22:52 11m だめだった 2022/06/22 22:52 ES2022でもだめ e
- タいしゅうてきには "module": "commonjs",
モジュールの CommonJS形式と ES Modules 形式
- ES Modules に sが付くとロクからして難しい
- わかりやすいQiita tsconfigのmoduleとtargetには何を設定すればいいか - TypeScript - Qiita
- 短くて分かりや良い生地
- import/export が ES2015 ES modules
- require/exports (CommonJS)
- たったのこれだけだよなあ
再び、上手くいった練習と見比べ
- ちゃんとテストがうごいてる jest_rensyuu と見比べたり、jest_rensyuu に合わせていって、設定には問題なく、コードに問題があることを発見した
- export - JavaScript | MDN
- 書き方が大量にありすぎて難しすぎる js 2022/06/24 1:31
- jest_rensyuu では ES modules で上手くいってるのでこのままでいけそうな気もしなくもない。
- export default と export const で違いがあるらしい (default export, named export)
- 多分、 named export は、呼ぶ側でその名前を指定しないとimport できない
- export default とexport constの違い - Qiita
- 中途半端には jest は es modules export, import に対応してそう 2022/06/25 0:35
- 役立った素晴らしい記事
少し前進
- export const add_marumaru = function (hikisuu1, hikisuu2, hikisuu3) { みたいな形式から export function add_marumaru (hikisuu1, hikisuu2, hikisuu3) { にしたら進みだした
やっと解決編
- ファイルの名前を marumaru.js から marumaru.ts にしたらじごくくの Must use import to load ES Module: C:\Users\tetsuo_yamada\marumaru_jest\src\marumaru.js がたなくなった
- ts-loader みたいなのが挟まってるから?(?)
- やってればおいおい分かるだろう(?)
普通にjestを書いていく編
- referenceerror document is not defined jest
- よくあるエラーぽい
- jest の環境ではそのままだと docuent がないよと。 2022/06/26 21:13
- ぴったりそうな記事
数あるJavaScriptテストツールの中からjestを選んだのは、jest-puppeteer、jest-image-snapshotなどpuppeteer関連で使い勝手が良さそうだったからです。
- puppeteer がいるのかな ?
- 要らなさそうだった 2022/07/05 1:41
作成時にテスト環境としてnode.jsかjsdomを選択していると思います。node.j指定だとこれからのテストでdocument is not definedとエラーになるためjsdomを指定します。
- // testEnvironment: "node",
- testEnvironment: "jsdom",
- なるほど。頼れる
- npm install jest-environment-jsdom がいりそう
alert をテストする編 2022/07/05 1:42
- 素晴らしい記事
- 5分でできた! (本記事の冒頭のコードを書いた)
感想
- JSは書き方がたくさんあってタイへん
この次
- 多分、運用できる状態を整えて、1関数分テストを完備して、導入する
- TSまで行けるか?
- 似た部分が多い関数なのでなんとか集約できるかも