> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 以 Testbench Workbench 推進套件開發

> 說明如何使用 Orchestra Testbench Workbench，建立具備路由、Migration、服務啟動並接近實際應用程式的驗證環境。

## 什麼是 Testbench Workbench

[Orchestra Testbench](https://github.com/orchestral/testbench) 是為測試設計，但搭配 Workbench 使用，可於套件儲存庫內建立小型 Laravel 應用程式並在本機執行。

在補足以 `package-testing` 建立的測試同時，適合用於 UI 確認、路由連通、附 Seeder 的驗證。

```mermaid theme={null}
flowchart TD
    A["套件本體<br>`src/`"] --> B["Workbench<br>`workbench/`"]
    B --> C["WorkbenchServiceProvider<br>Demo 用服務註冊"]
    B --> D["路由、Controller<br>畫面確認"]
    B --> E["Migration、Seeder<br>資料驗證"]
    B --> F["`composer serve`<br>本機啟動"]
    C --> G["testbench.yaml<br>Provider/Build 設定"]
```

## 設定

<Steps>
  <Step title="安裝 Testbench">
    ```bash theme={null}
    composer require --dev orchestra/testbench
    ```
  </Step>

  <Step title="建立 Workbench">
    ```bash theme={null}
    vendor/bin/testbench workbench:install
    ```

    此指令會一併執行以下作業：

    * 建立 `workbench/` 目錄結構
    * 於 `composer.json` 的 `autoload-dev` 加入 Workbench 命名空間
    * 於 `composer.json` 的 `scripts` 加入 build 用指令

    <Tip>
      附加選項：

      * `--force`：覆寫既有檔案
      * `--basic`：省略路由與 package discovery 設定的簡潔配置
      * `--devtool`：啟用 DevTool 支援
    </Tip>
  </Step>

  <Step title="Build 並啟動">
    ```bash theme={null}
    composer clear
    composer prepare
    composer build
    vendor/bin/testbench serve
    ```
  </Step>
</Steps>

<Info>
  `workbench:install` 會一併整備 `workbench/` 目錄、`autoload-dev` 及相關 script。
</Info>

安裝後，`composer.json` 會加入以下 script。

```json theme={null}
{
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/",
            "Workbench\\App\\": "workbench/app/",
            "Workbench\\Database\\Factories\\": "workbench/database/factories/",
            "Workbench\\Database\\Seeders\\": "workbench/database/seeders/"
        }
    },
    "scripts": {
        "post-autoload-dump": [
            "@clear",
            "@prepare"
        ],
        "clear": "@php vendor/bin/testbench package:purge-skeleton --ansi",
        "prepare": "@php vendor/bin/testbench package:discover --ansi",
        "build": "@php vendor/bin/testbench workbench:build --ansi",
        "serve": [
            "Composer\\Config::disableProcessTimeout",
            "@build",
            "@php vendor/bin/testbench serve --ansi"
        ]
    }
}
```

## 以 testbench.yaml 定義開發環境

Workbench 的行為由置於根目錄的 `testbench.yaml` 管理。

<Warning>
  `testbench.yaml` 可能包含依環境不同的設定，建議加入 `.gitignore` 使其排除於 commit 對象之外。改為在儲存庫中放置 `testbench.yaml.example` 作為範本。
</Warning>

```yaml theme={null}
providers:
  - Vendor\Package\PackageServiceProvider
  - Workbench\App\Providers\WorkbenchServiceProvider

migrations:
  - workbench/database/migrations

workbench:
  start: '/'
  install: true
  health: false
  discovers:
    web: true
    api: false
    commands: false
    components: false
    views: false
    config: true
  build:
    - asset-publish
    - create-sqlite-db
    - db-wipe
    - migrate-fresh:
        --seed: true
        --seeder: Workbench\Database\Seeders\DatabaseSeeder
  assets:
    - laravel-assets
```

主要設定選項：

| key                   | 說明                           |
| --------------------- | ---------------------------- |
| `providers`           | 於 Workbench 環境載入的服務提供者清單     |
| `migrations`          | 執行的 Migration 目錄             |
| `workbench.start`     | 執行 `composer serve` 時的預設 URL |
| `workbench.discovers` | 控制 Laravel 套件自動偵測的對象         |
| `workbench.build`     | build 時執行的指令清單               |

環境變數也可透過 `testbench.yaml` 管理。

```yaml theme={null}
env:
  - APP_ENV=testing
  - APP_KEY=base64:your-app-key
  - DB_CONNECTION=sqlite
  - DB_DATABASE=:memory:
```

## workbench 目錄結構

<Tree>
  <Tree.Folder name="workbench" defaultOpen>
    <Tree.Folder name="app" defaultOpen>
      <Tree.Folder name="Http">
        <Tree.Folder name="Controllers" />
      </Tree.Folder>

      <Tree.Folder name="Models" />

      <Tree.Folder name="Providers">
        <Tree.File name="WorkbenchServiceProvider.php" />
      </Tree.Folder>
    </Tree.Folder>

    <Tree.Folder name="bootstrap" />

    <Tree.Folder name="config" />

    <Tree.Folder name="database" defaultOpen>
      <Tree.Folder name="factories" />

      <Tree.Folder name="migrations" />

      <Tree.Folder name="seeders">
        <Tree.File name="DatabaseSeeder.php" />
      </Tree.Folder>
    </Tree.Folder>

    <Tree.Folder name="public" />

    <Tree.Folder name="resources">
      <Tree.Folder name="views" />
    </Tree.Folder>

    <Tree.Folder name="routes">
      <Tree.File name="web.php" />

      <Tree.File name="api.php" />

      <Tree.File name="console.php" />
    </Tree.Folder>

    <Tree.Folder name="storage" />
  </Tree.Folder>
</Tree>

## Workbench 提供的主要功能

### WorkbenchServiceProvider

建立 Workbench 專用的服務提供者，執行 Demo 用的註冊處理。

```php theme={null}
<?php

namespace Workbench\App\Providers;

use Illuminate\Support\ServiceProvider;
use Vendor\Package\SomeClass;
use Workbench\App\Services\DemoService;

class WorkbenchServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(DemoService::class);
    }

    public function boot(): void
    {
        SomeClass::register('demo', DemoService::class);
        $this->loadRoutesFrom(__DIR__.'/../../routes/web.php');
        $this->loadViewsFrom(__DIR__.'/../../resources/views', 'workbench');
    }
}
```

### 路由與 Controller

可在 `workbench/routes/web.php` 或 `workbench/routes/api.php` 放置驗證路由。

```php theme={null}
use Illuminate\Support\Facades\Route;
use Vendor\Package\Facades\Package;

Route::get('/', function () {
    return Package::status();
});
```

### Migration 與 Seeder

使用 `workbench/database/migrations` 與 `workbench/database/seeders`，可以以接近實際運行的資料結構驗證。

```php theme={null}
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::create('widgets', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->timestamps();
});
```

以 Seeder 產生測試資料。

```php theme={null}
<?php

namespace Workbench\Database\Seeders;

use Illuminate\Database\Seeder;
use Workbench\Database\Factories\UserFactory;

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        UserFactory::new()->count(10)->create();
    }
}
```

### 啟動服務與 CLI 確認

可透過 `vendor/bin/testbench` 執行 Artisan 指令。

```bash theme={null}
vendor/bin/testbench list
vendor/bin/testbench route:list
vendor/bin/testbench migrate:fresh --seed
```

## 使用 WithWorkbench trait 測試

使用 `WithWorkbench` trait 後，`testbench.yaml` 的設定也會套用至自動測試。

```php theme={null}
<?php

namespace Tests;

use Orchestra\Testbench\Concerns\WithWorkbench;
use Orchestra\Testbench\TestCase as Orchestra;

abstract class TestCase extends Orchestra
{
    use WithWorkbench;

    protected function getPackageProviders($app): array
    {
        return [
            \Vendor\Package\Providers\YourServiceProvider::class,
        ];
    }

    protected function defineEnvironment($app): void
    {
        $app['config']->set('database.default', 'testing');
        $app['config']->set('your-package.key', 'test-value');
    }
}
```

## 與測試的搭配

若將 Workbench 作為「手動確認、Demo 用應用程式」、Testbench 的測試程式碼作為「自動驗證」分工，較易操作。

* 自動化：於 `tests/` 防止 regression
* 手動確認：於 `workbench/` 確認畫面、動線、整合行為

## 疑難排解

```bash theme={null}
# 清除並完整 rebuild
composer clear && composer prepare && composer build

# 確認套件自動偵測
vendor/bin/testbench package:discover --ansi

# 確認設定
vendor/bin/testbench about

# 確認路由清單
vendor/bin/testbench route:list
```

<AccordionGroup>
  <Accordion title="Workbench 無法 build">
    請確認 `testbench.yaml` 的語法與 Provider 設定。YAML 的縮排錯誤可能為原因。
  </Accordion>

  <Accordion title="路由未被載入">
    請確認路由檔案路徑與 WorkbenchServiceProvider 的註冊。確認 `testbench.yaml` 的 `discovers.web` 是否為 `true`。
  </Accordion>

  <Accordion title="發生資料庫錯誤">
    請確認 Migration 的路徑是否正確。若使用 SQLite，請確認是否包含 `create-sqlite-db` build 步驟。
  </Accordion>
</AccordionGroup>

## 相關頁面

<Columns cols={2}>
  <Card title="以 Orchestra Testbench 測試 Laravel 套件" icon="flask-conical" href="/zh-TW/advanced/package-testing">
    先確認套件測試基礎的建立方式。
  </Card>

  <Card title="套件的版本相容性管理" icon="git-branch" href="/zh-TW/advanced/package-versioning">
    確認 Laravel 與 Testbench 的對應表及 CI matrix 運行。
  </Card>
</Columns>

<Info>
  Source: [invokable/laravel-bluesky docs/workbench.md](https://github.com/invokable/laravel-bluesky/blob/main/docs/workbench.md), [Orchestra Testbench](https://github.com/orchestral/testbench)
</Info>


## Related topics

- [以 Orchestra Testbench 測試 Laravel 套件](/zh-TW/advanced/package-testing.md)
- [Laravel 套件開發](/zh-TW/advanced/package-development.md)
- [套件自動偵測的內部結構](/zh-TW/advanced/package-discovery.md)
- [GeneratorCommand — 自訂 make: 指令的實作](/zh-TW/advanced/generator-command.md)
- [套件的 CHANGELOG 與發布管理](/zh-TW/advanced/package-changelog.md)
