---
title: "匯入前端實作 - Cucumber 的文件測試法"
date: 2024-05-10T00:00:00+08:00
publishDate: 2024-05-10T00:00:00+08:00
lastmod: 2023-12-06T15:50:15+08:00
tags: ["Cucumber","教學","測試","後端","Rails","ViteRuby","Vite"]
series: "test-with-cucumber"
toc: true
permalink: "https://blog.aotoki.me/posts/2024/05/10/test-with-cucumber-import-frontend-implementation/"
language: "zh-tw"
---


我們在前面的練習中大部分的實作都是可以直接沿用，唯一需要重新處理的是 Cucumber 的步驟定義，他會受到使用的語言、框架需要重新撰寫，接下來我們會先將前端的實作搬移到 Rails 中讓專案能夠運作起來。

<!--more-->

## 搬移前端實作{#move-frontend}

我們只需要把 Vite 專案中的 `src/` 目錄下除了 `main.ts` 所有檔案複製到 Rails 專案的 `app/javascript` 目錄，然後針對 `app/javascript/entrypoints/application.ts`  進行修改。

```ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from '@/App.vue'

const pinia = createPinia()
const app = createApp(App)

app.use(pinia)
app.mount('#app')
```

實際上也就是原本的 `src/main.ts` 檔案的內容，並且將 `import App from './App.vue'` 修改為 `import from '@/App.vue'` 來配合新的檔案路徑相對關係。

另一方面，因為 ViteRuby 使用的模式預設沒有支援 `import.meta` 而且在統一由 Rails 作為 Web Server 的狀況下，我們基本上也不需要指定 API 伺服器的位置，因此將 `app/javascript/api.ts` 的內容稍做調整。

```ts
const API_SERVER = ''

// ...
```

因為我們還沒有安裝 Pinia 到專案中，因此還需要額外運行 `yarn add piana@2.1.3` 將依賴的套件加入到裡面，這時候運行 `./bin/dev` 會發現有一部分畫面無法顯示，這是因為後端的 API 還沒有被加入進來。

## 定義路由{#define-routes}

這個階段的目標是確認前端順利被加入到專案中，因此我們先對 Rails 把所需的 API 路由定義下來，並且修改 `config/routes.rb` 將原本實作的 API 路由加入到專案裡面。

```ruby
# ...
Rails.application.routes.draw do
  # ...

  namespace :api do
    resources :products, only: %i[index]
    resource :cart, only: %i[show create]
    resource :checkout, only: %i[create]
  end
end
```

並且針對這幾個路由加入對應的 Controller 並且死回傳內容。

```ruby
# app/controllers/api/products_controller.rb
module Api
  class ProductsController < ActionController::API
    def index
      render json: [
        { id: 1, name: 'Ruby 秘笈', price: 100 },
        { id: 2, name: 'RSpec 秘笈', price: 150 }
      ]
    end
  end
end
```

```ruby
# app/controllers/api/carts_controller.rb
module Api
  class CartsController < ActionController::API
    def show
      render json: []
    end

    def create
      render json: []
    end
  end
end
```

```ruby
# app/controllers/api/checkouts_controller.rb
module Api
  class CheckoutsController < ActionController::API
    def create
      render json: { text: '結帳成功' }
    end
  end
end
```

這樣一來我們理論上要能夠通過一部分的測試，先將原本 Vite 專案下 `features/products.feature` 的內容放到 Rails 專案下，打開 `features/step_definitons/common.rb` 先將用於建立假資料的步驟定義進去，讓測試可以執行到場景的部分。

```ruby
# ...

Given('這裡有一些商品') do |table|
end

Then('可以看見商品 {string}') do |name|
  expect(page).to have_text(name)
end
```

這樣一來，我們運行 `bundle exec cucumber` 的時候就可以通過第一項看到商品的測試，接下來只需要繼續完善後端的實作，就可以讓所有的測試都能夠順利通過。

