VSCodeでjestのスナップショットの簡易スニペットを作成

こんにちは、いわむらです

今回はタイトルにある通り、VSCodeでjestのスナップショットの簡易スニペットを作成してみようかと思います

自社のフロントエンド開発で新規コンポーネントには最低限のテストとして、スナップショットの作成が必須でして、新規コンポーネントを作成する時に毎回新しいテストを作成するのですが、基本的にはimport文などは共通だったりするので他のファイルからコピペしてました

もう少し便利にできないかなと思っていたので今回初めてだったのですがスニペットを作成してみようと思い作成してみました

今回のスニペット作成環境は以下のバージョンで確認しました

vscode: 1.58
nuxt: 2.14
jest: 27.0
typescript: 4.1

まず cmd + shift + pでコマンドパレットが開くのでそこで user snippetsと検索しましょう

そうすると添付するキャプチャのように選択肢が絞られると思います

「Preferences: Configure User Snippets」を選択すると更にVSCodeを利用する時に必ず適応させるグローバルなスニペットを作成するか、ワークスペース毎作成するか等の選択肢がでるかと思います。

今回はワークスペースのスニペットを作成するようにします

「New Snippets file for 'XXXXX'...」を選択するとスニペットファイルの名前を入力するように促されるのでワークスペースのプロジェクト名などを入力してEnterを入力してください

そうすると xxxxxx.code-snippets として自動生成されたファイルができるかと思います

{
  "Print to console": {
    "scope": "javascript,typescript",
    "prefix": "log",
    "body": [
      "console.log('$1')",
      "$2"
    ],
    "description": "Log output to console"
  }
}

生成されたコードを元にスニペット作成の基本的な部分を説明します

"Print to console" は IntelliSenseを表示されたときに説明文的な役割をする部分です

"scope"はどの言語でスニペットを利用するかを指定する部分です

"prefix"はスニペットを候補として出すさいのトリガーとなる文字です

"body"はスニペットを選択した時に出力される文字列ですインデックスが行になります

"description"はスニペットを選択した時に表示される詳細説明の部分です

'$1', '$2'の記述がありますがこれはスニペットを展開した時にカーソルの位置を決めるための記述です

'$1'が展開したときの一番最初のカーソル位置

'$2'がタブを押した時に次にくるカーソル位置

となります

上記のコードを参考にスナップショットテストの共通部分を作成してみました

  "Component Base Test": {
    "scope": "typescript",
    "prefix": "basetest",
    "body": [
      "import { mount } from '@vue/test-utils'",
      "import ${TM_FILENAME/(.)\\..+$/$1/} from '@\/${RELATIVE_FILEPATH/(test\\/)(.*)(\\.test.ts)/$2/}.vue'",
      "",
      "describe('${RELATIVE_FILEPATH/(test\\/)(.*)(\\.test.ts)/$2/}', () => {",
      "\ttest('スナップショットが一致するかどうか', () => {",
      "\t\tconst wrapper = mount(${TM_FILENAME/(.)\\..+$/$1/}, {",
      "\t\t\tpropsData: {",
      "\t\t\t\t${2:isTest: true,}",
      "\t\t\t},",
      "\t\t})",
      "\t\texpect(wrapper.vm.\\$el).toMatchSnapshot()",
      "\t})",
      "})",
      ""
    ],
    "description": "create component base test"
  }

テストファイルの命名規則はコンポーネント名.test.tsなのでButtonコンポーネントの場合は、Button.test.tsとなります

この中で苦労したのが正規表現が苦手だったためにテストするコンポーネントのimportを記述するのが大変でした

"import ${TM_FILENAME/(.)\..+$/$1/} from '@/${RELATIVE_FILEPATH/(test\/)(.*)(\.test.ts)/$2/}.vue'",

${TM_FILENAME}を利用していますがこれを記述すると現在のファイル名を出力してくれます

Button.test.tsが出力されるイメージです

${TM_FILENAME のあとに正規表現を使うことで必要な部分だけを切り取ることができます

"import ${TM_FILENAME/(.)\..+$/$1/} from

"import Button fromと出力されます

次に${RELATIVE_FILEPATH}はワークスペースまたは開いているフォルダーからの現在作成しているファイルまでのパスを出力していくれます

ワークスペースをappとしてapp/test/component/atoms/button.test.tsでスニペットの展開を実行した場合は

test/component/atoms/button.test.tsが出力されるイメージです

${RELATIVE_FILEPATH}も同じく正規表現を使うことで必要な部分だけを切り取ることができます

'@/${RELATIVE_FILEPATH/(test\/)(.*)(\.test.ts)/$2/}.vue'"

'@/components/atoms/Button.vue'"と出力されます

他に \tはインデント、 ""は空文字は改行として利用しています

これでテストファイルにて basetest を入力してスニペットを選択すると共通部分が出力されるようになりました

微々たる部分ではありますがこれからも小さいことでも開発に貢献できればと思います

最後まで読んでいただきありがとうございました。