コンテンツにスキップ

ファイルアップロード上限を正しくテストする方法

カテゴリ:テスト技法

Webアプリケーションのファイルアップロード機能を開発したとき、「上限は10MBに設定した」と安心していませんか? 実は、アップロード上限のテストには多くの落とし穴があり、正しく検証しないと本番環境で予期しないエラーが発生します。この記事では、境界値テストの考え方を使って、アップロード上限を正確にテストする方法を解説します。

境界値テストとは

境界値テスト(Boundary Value Testing)は、ソフトウェアテストにおける基本的な技法のひとつです。入力値の境界付近、つまり「ちょうど上限」「上限の1バイト手前」「上限の1バイト超過」といったポイントでバグが発生しやすいという経験則に基づいています。

ファイルアップロードの上限テストでは、最低でも以下の3つのテストケースを用意すべきです。

  • 上限ちょうどのファイル — アップロードが成功するか確認
  • 上限より1バイト小さいファイル — 確実に成功するか確認
  • 上限より1バイト大きいファイル — 正しく拒否されるか確認

MB と MiB の混同に注意

アップロード上限のテストで最もよくあるミスは、MB(メガバイト)と MiB(メビバイト)の混同です。

  • 1 MB = 1,000,000 バイト(10進数ベース、SI単位)
  • 1 MiB = 1,048,576 バイト(2進数ベース、IEC単位)

この差は約4.86%あり、10MBと10MiBでは48,576バイトもの違いがあります。サーバー側のフレームワークやクラウドサービスがどちらの単位を使っているかを正確に把握することが重要です。例えば、PHPの upload_max_filesize で「10M」と指定した場合、これは10MiB(10,485,760バイト)として解釈されます。一方、一部のCDNやAPIゲートウェイでは10MB(10,000,000バイト)として扱う場合もあります。

multipart/form-data のオーバーヘッド

ファイルアップロードで使われる multipart/form-data 形式には、ファイル本体以外にも boundary 文字列、Content-Disposition ヘッダー、改行コードなどのオーバーヘッドが含まれます。

サーバー側の上限チェックがリクエストボディ全体に対して行われる場合、ファイル本体が上限以下でも、オーバーヘッドを含めると超過してしまうことがあります。Nginx の client_max_body_size はリクエストボディ全体のサイズを制限するため、この点に注意が必要です。

# Nginx の設定例
client_max_body_size 10m;  # リクエストボディ全体の上限(MiB単位)

フロントエンドとバックエンドの二重チェック

テスト時には、フロントエンド(JavaScript)とバックエンド(サーバー)の両方でサイズチェックが行われているかを確認しましょう。フロントエンドだけでチェックしている場合、開発者ツールや curl コマンドで簡単にバイパスできます。

// フロントエンドでのサイズチェック例
const MAX_SIZE = 10 * 1024 * 1024; // 10 MiB
fileInput.addEventListener('change', (e) => {
    const file = e.target.files[0];
    if (file.size > MAX_SIZE) {
        alert('ファイルサイズが上限を超えています');
        e.target.value = '';
    }
});

エラーメッセージとUXの確認

境界値テストでは、単にリクエストが成功/失敗するかだけでなく、以下の点もチェックしましょう。

  • 上限超過時に分かりやすいエラーメッセージが表示されるか
  • HTTPステータスコードは適切か(413 Payload Too Large など)
  • 大きなファイルのアップロード中にプログレスバーが正しく動作するか
  • タイムアウトの処理が適切に行われるか

テスト用ファイルの入手方法

正確な境界値テストには、バイト単位でサイズが正確なテスト用ファイルが必要です。DevLab では、主要なアップロード上限に合わせた境界値テスト用ファイルを提供しています。

すべてのファイルにはMD5・SHA-1・SHA-256ハッシュ値を記載しているため、ダウンロード後の整合性確認にもご活用ください。

まとめ

ファイルアップロード上限のテストは、単に「大きいファイルを投げてみる」だけでは不十分です。MBとMiBの違いを理解し、multipart オーバーヘッドを考慮し、バイト単位で正確なテストファイルを使って境界値を検証しましょう。DevLab の境界値テスト用ファイルを活用すれば、これらのテストを効率よく実施できます。

📚 関連記事

PNG vs WebP vs AVIF|画像フォーマットの選び方と変換方法

PNG / JPEG / WebP / AVIF の特徴・用途・ブラウザ対応状況を比較。picture 要素での出し分け、DevLab の画像フォーマット変換ツールの使い方も解説。

2026-04-18

Whois でドメイン情報を調べる方法|有効期限・ネームサーバー・登録者

Whois でわかること (登録者・有効期限・レジストラ・NS)、GDPR によるプライバシー保護の影響、ドメイン管理の実務的な使い方を解説。

2026-04-18

HTTP ステータスコード完全ガイド|よくあるエラーの原因と対処法

開発者が頻出する HTTP ステータスコード (200/301/302/400/401/403/404/413/422/429/500/502/503/504) の意味・原因・対処法を解説。301 vs 302 の SEO 影響、400 vs 422 の使い分けも。

2026-04-18

cURL コマンドを JavaScript fetch・Python requests に変換する方法|DevTools 連携

Chrome DevTools の Copy as cURL を fetch / axios / Python requests / PHP cURL / Go net/http に変換する手順を解説。主要 cURL オプション (-X / -H / -d / -F / -u / -b / -L) の変換パターン、認証トークンの扱い、注意点まで。

2026-04-16

Cookie のセキュリティフラグ完全ガイド|Secure / HttpOnly / SameSite / __Host-

Cookie のセキュリティ属性 Secure / HttpOnly / SameSite (Strict/Lax/None) / __Host- __Secure- プレフィックス / 4096 バイト制限を解説。CSRF / XSS / セッションハイジャック対策と、Laravel / Express の実装例。

2026-04-16

JWT のセキュリティベストプラクティス|alg none 攻撃 / 有効期限 / 署名検証

JWT (JSON Web Token) の代表的な脆弱性 6 種類 (alg none 攻撃 / 鍵混同 / 無期限トークン / payload への機密情報 / 失効不可 / 弱いシークレット) と対策。リフレッシュトークンパターン、失効リスト、HttpOnly Cookie 格納まで。

2026-04-16