0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LaravelでCSVデータを使ってDBにテストデータを作成する方法

Posted at

LaravelでCSVデータをmysqlへ登録する処理を作成したので、その方法を説明します。

LaravelでMySQLに登録しているデータを取得するAPIがあり、自動テストを行う際に、テスト用データを作成したいのですが、テストメソッドの中でfactoryを使用してデータを作成すると、テストコードが冗長化して見づらくなってしまいます。

テストコードにはテストのロジックだけを書きたいため、テストデータの作成は外部ファイル(CSVファイル)に定義し、テスト実行時にデータを作成する処理を含めないようにするため、LaravelでCSVデータをmysqlへ登録するようにしました。

ロジックの内容

CSVファイルにテストで使用するDBのデータを作成して、それをテストコード実行するときにインポートしてテストデータを作成する。

CSVはテストケースごとにディレクトリを分けて、1つのテストケースで登録したいDBごとにcsvファイルを分けることにする。

csvファイル名はDB名と同じ名前にして、一致する名前のDBにcsvの内容を登録するものとする。

ディレクトリ構造

database
 ┗ seeders
  ┗ CsvToDataSeeder.php //csvファイルの中のCSVをすべてmysqlに登録する

tests
 ┗ csv
  ┗ testCase1
   ┗ 各CSVファイル(ファイル名はDB名と同じにする)
 ┗ Feature
  ┗ ***Test.php

実際のコード

CsvToDataSeeder.php
namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class CsvToDataSeeder extends Seeder
{
    public function run(string $testCaseName): void
    {
        // テストケース名に一致するディレクトリ内の全てのCSVファイルを取得
        $files = glob(base_path("tests/csv/{$testCaseName}/*.csv"));

        foreach ($files as $file) {
            // CSVファイルを読み込む
            $csv_data = $this->csvToArray($file);

            // ファイル名からテーブル名を取得(拡張子.csvを削除)
            $tableName = basename($file, '.csv');

            // データベースに挿入するためのデータの作成
            $insert_data = [];
            foreach ($csv_data as $row) {
                // 'null'文字列をNULLに変換
                foreach ($row as $key => $value) {
                    if ($value === 'null') {
                        $row[$key] = null;
                    }
                }
                $insert_data[] = $row;
            }
            // データベースに挿入
            DB::table($tableName)->insert($insert_data);
        }
    }

    protected function csvToArray($filename)
    {
        $rows = [];
        if (($handle = fopen($filename, 'r')) !== false) {
            $header = fgetcsv($handle, 0, ','); // ヘッダー行を読み込む
            while (($row = fgetcsv($handle, 0, ',')) !== false) {
                $rows[] = array_combine($header, $row);
            }
            fclose($handle);
        }
        return $rows;
    }
}

runメソッド内容について

このクラスは、CSVファイルからデータを読み込み、それをデータベースに挿入します。

runメソッドは引数に「テストケース名」を受け取っています。
テストケース名に一致するディレクトリ内の全てのCSVファイルを取得し、それぞれのファイルに対してDBに登録する処理を行います。

各CSVファイルはcsvToArrayメソッドによって配列に変換され、その後、ファイル名からテーブル名のみを取得します(拡張子.csvを削除)。

次に、データベースに挿入するためのデータを作成します。

各行に対して、'null'文字列をNULLに変換し、それぞれの値を上書きします。
そして、その行を挿入データの配列に追加します。

最後に、DB::table($tableName)->insert($insert_data);を使用して、データをデータベースに挿入します。

csvToArrayメソッドの内容について

csvToArrayメソッドは、指定されたCSVファイルを開き、ヘッダー行を読み込みます。
その後、各行を読み込み、ヘッダーと行の値を組み合わせて配列を作成します。
これを繰り返し、全ての行を処理したら、ファイルを閉じて配列を返します。


***Test.php
// テストデータを作成
$seeder = new CsvToDataSeeder();
$seeder->run('testCase1');

自動テストのファイルの中で、runメソッドを実行します。
引数にテストケース名を渡すことで、CsvToDataSeeder.phpの中で同一名のディレクトリ内のcsvファイルをすべてDBに登録できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?