Vue 3のE2Eテスト：Cypressを使ったログインコンポーネントの検証

## はじめに
現代のWeb開発において、End-to-End（E2E）テストはアプリケーションの品質保証に不可欠です。本記事ではVue 3アプリケーションでCypressを使用したログインコンポーネントのテスト実装例を紹介します。

## プロジェクト構成
### 主な技術スタック
- Vue 3 (Composition API)

- TypeScript

- Cypress 14.1

- Vite

## パッケージ構成
```package.json
{
  "dependencies": {
    "vue": "^3.5.13"
  },
  "devDependencies": {
    "cypress": "^14.1.0",
    "vite": "^6.1.0",
    "typescript": "~5.7.3"
  }
}
```

## ログインコンポーネントの実装
### 主な機能
- メール/パスワードバリデーション

- API通信の状態管理

- エラーメッセージ表示

- パスワード強度チェック

```Login.vue
<template>
  <!-- 簡略化されたテンプレート構造 -->
  <form @submit.prevent="handleLogin">
    <input v-model="email" @blur="validateEmail" />
    <p v-if="emailError" class="error-message">{{ emailError }}</p>
    
    <input v-model="password" @blur="validatePassword" />
    <p v-if="passwordWarning" class="warning-message">{{ passwordWarning }}</p>
    
    <button :disabled="isLoginDisabled || isLoading">
      {{ isLoading ? 'ログイン中...' : 'ログイン' }}
    </button>
  </form>
</template>
```
## Cypressテストの実装
### テスト戦略
1. フォームレンダリングの検証

2. バリデーション機能のテスト

3. API通信のモック処理

4. 成功/失敗シナリオの網羅

### テストケース例
1. フォーム初期状態の検証
    ```login.cy.js
    it('ログインフォームを正しくレンダリングする', () => {
      cy.get('h2').should('contain', 'ログイン「テスト」');
      cy.get('button[type="submit"]').should('be.disabled');
    });
    ```
2. メールバリデーション
    ```login.cy.js
    it('メール形式を検証する', () => {
      cy.get('input[type="email"]')
        .type('invalid-email')
        .blur();
      cy.get('.error-message').should('contain', '有効なメールアドレス');
    });
    ```
3.  API通信のモック
    ```login.cy.js
    beforeEach(() => {
      cy.intercept('POST', 'src/services/auth', (req) => {
        if (req.body.email === 'test@example.com') {
          req.reply({ statusCode: 200, body: { token: 'mock-jwt-token' } });
        } else {
          req.reply({ statusCode: 401, body: { message: '認証エラー' } });
        }
      }).as('loginRequest');
    });
    ```  
4. ログイン成功テスト
    ```login.cy.js
    it('成功したログインを処理する', () => {
      cy.get('input[type="email"]').type('test@example.com');
      cy.get('input[type="password"]').type('Password123');
      cy.get('button[type="submit"]').click();
      
      cy.get('.success-message').should('contain', 'ログインが成功');
      cy.screenshot('after-login-success');
    });
    ```
5. ログイン失敗テスト
    ```login.cy.js
    it('失敗したログインにエラーメッセージを表示する', () => {
      cy.get('input[type="email"]').type('wrong@example.com')
      cy.get('input[type="password"]').type('WrongPass123')
      cy.get('button[type="submit"]').click()
      cy.get('.error-message').should('contain', 'ログインメールとパスワードは一致しません')

      cy.screenshot('after-login-failure');
    })
    ```


## テスト実行設定
```cypress.config.ts
export default defineConfig({
  e2e: {
    baseUrl: "http://localhost:5173/",
    video: true,
    screenshotOnRunFailure: true,
  },
  component: {
    devServer: {
      framework: "vue",
      bundler: "vite",
    },
  },
});
```
## 実行コマンド
```
# 開発モードで起動
npm run test:e2e:dev

# CIモードで実行
npm run test:e2e
```

## テスト実行デモ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3951101/ef9c1018-6ca6-4081-80d3-ccbd404fc3e8.png)


![login.cy.js.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3951101/ae203b01-8d72-4b05-bc95-f5872f84e050.gif)

## まとめ
Cypressを活用することで、Vue 3アプリケーションの主要ユーザーフローを効果的にテストできます。この記事では実際のコード例を交えながら、Vue 3アプリケーションにおけるCypressの実践的な活用方法を解説しました。テストの自動化により、リファクタリング時の安心感やユーザー体験の安定性が大きく向上します。次のステップとして、コンポーネントテストやVisual Regressionテストの導入も検討してみるとよいでしょう。