點燈坊

失くすものさえない今が強くなるチャンスよ

使用 Docker Compose + MSW 執行 Cypress (Vite)

Sam Xiao's Avatar 2021-06-05

雖然可以在 Cypress 的 Test 對 API 加以 Mock,但也可以使用 MSW 負責 Mock,Cypress 則完全負責 Test。

Version

Vue 3.0.11
Cypress 7.4.0
MSW 0.29.0

Docker Compose

docker-compose.yml

version: "3"
services:
  vue:
    image: nginx:alpine
    restart: always
    ports:
      - "8080:80"
    volumes:
      - ./dist:/usr/share/nginx/html
  cypress:
    image: cypress/included:7.4.0
    environment:
      - CYPRESS_baseUrl=http://vue
    volumes:
      - ./cypress:/cypress
      - ./cypress.json:/cypress.json
    command: npx cypress run

第 3 行

vue:
  image: nginx:alpine
  restart: always
  ports:
    - "8080:80"
  volumes:
    - ./dist:/usr/share/nginx/html

設定 Vue container:

  • image: nginx:alpine:使用 Nginx 官方所提供 image
  • ports::設定對外為 port 8080,對內為 port 80
  • volumns:將 dist 目錄對應用 container 內部的 /usr/share/nginx/html

10 行

cypress:
  image: cypress/included:7.4.0
  environment:
    - CYPRESS_baseUrl=http://vue
  volumes:
    - ./cypress:/cypress
    - ./cypress.json:/cypress.json
  command: npx cypress run

設定 Cypress container:

  • image: cypress/included:7.4.0:使用 Cypress 官方所提供 image
  • environment:設定 baseUrl 環境變數,直接指向 vue container
  • volumes:將專案的 cypress 目錄與 cypress.json 設定檔對應到 container 內部
  • command: npx cypress run:執行 Cypress

CYPRESS 為開頭的變數將成為 Node 環境下的全域變數

Main

main.js

import { createApp } from 'vue'
import worker from '/src/mock'
import App from './App.vue'

if (import.meta.env.MODE === 'mock')
  worker.start()

createApp(App).mount('#app')

import.meta.env.MODE 判斷目前的 mode,若為 mock 則啟動 MSW。

NPM Script

package.json

"scripts": {
  "test:docker": "yarn build --mode mock && docker compose up",
  "mock": "vite --mode mock"
},
  • test:docker:以 docker compose 執行,在 yarn build 之後加上 --mode mock 表示以 mock 模式編譯
  • mock:以 vite 執行,vite 之後加上 --mock mock 表示以 mock 模式執行

Conclusion

  • 直覺會想在 docker-compose.ymlenvironment 設定環境變數啟動 MSW,但這只是設定了 Nginx 的環境變數,而 Vue 是跑在 browser 內,因此 Vue 無法讀取,必須在編譯時期就將環境變數準備好