質問: Access(データエントリー) - MySQL - WEB(帳票出力) お使いのプログラム言語は、一致していなくともかまいません。 以上、よろしくお願いいたします。
回答: > > 日付やautoincrementで自動採番されたりする項目があり、順番が上手く並ばない > > > そもそもMySQLは挿入したデータを常に同じ順番で持つことを保証していません。 なので、取り出すSQLもセットで考える必要があります。 > > データ登録、データ出力を手動で行っており、変更後の差分確認まで時間がかかる。 > > > テスティングフレームワークを使って自動化をしましょう。 使用言語とのAND検索でこれぞと言うものが出てくるかと思います。 全体的に見て得られた印象から回答します。 これは結合テストをコードレベルで解決したいという話でしょうか? しかし、質問内容の一文ではどうも単体テストの範囲の質問のようにも見受けられます。 > > データベースの更新ロジックを変更した場合、確認に時間がかかっています。 > > > 単体テストの鉄則ですが、1クラスや1メソッド単位でテストしてください。 上記を見る限り最低でも2~3クラスのやり取りを全て1個のロジックでこなそうとして自爆しているようにしか見えません。 質問内容から想定した順序です(仮の名前もわりふってみました) 1. Accessからデータを読み込む → 秘書さん 2. 読み込んだデータを計算 → ソロバン君 3. MySQLに格納 → 司書さん これらの3手順はオブジェクト指向言語で組んでいるならクラスによって分割され、 各々の担当業務をしっかりこなしてくれるプログラムであるべきです。 その上で、副作用のあるロジックと副作用のないロジックを分類していきます。 秘書さんが読み込むデータは、読み込むAccessファイルが同一ならば常に同じで、 読み込んだデータはそのまま結果としてソロバン君に渡されます。 なので副作用なし、Accessファイルは軽いものを複数個用意してプロジェクトのテストフォルダにでも突っ込んでおけば良いでしょう。 ソロバン君が計算して加工するデータは入力値が同一ならば出力値は同一なはずなのでこれも副作用なし。 残った司書さんですが、MySQLへの保存は書籍IDやら格納日時を勝手に付与し始めるので副作用があります。 なので、テストの度に作って壊せるテスト用のデータベースを用意しておくと良いでしょう。 もしくは、SQL文が入力値と出力値が等価になるようにして、SQLを作るまでのメソッド、作ったSQLをMySQLに入れるメソッドの2つを用意して、SQLを作るまでのメソッドを単体テストとするやり方でも十分でしょう。 次に、難関として残ったDB回りの単体テスト方針を考えていきます。 MySQLではDateTime型へのInsertはNow()でいけます。 なので、下記のようなSQLにすれば入力値と生成されるSQLは常に等価になりますね。 (SQL文はMySQLを想定、テスト用コードはわかり易さ優先のJavaScriptっぽい何かです) ``` -- 保存用SQL INSERT INTO books(user_id, name, modified, created) VALUES('1', 'リーダブルコード', now(), now()) ``` ``` // Assert.equalは2つの引数が等価で有るという宣言 Assert.equal( 司書.create_sql_of(ソロバン.calc(秘書.read(Accessのパス))), 保存用SQL ) ``` このSQL文をMySQLに1度発行して確認できれば、これは1行の挿入に成功することが保証されます。 なので、司書さんはこのSQL文を作成できればテスト終了とみなして良いでしょう。 もしnow()が使えない等の状況下では一度保存してから下記のSQLで取り出してみるって方法も使えると思います。 ``` -- 確認用SQL SELECT * FROM books WHERE name = 'リーダブルコード' LIMIT 1 ``` ``` before = MySQL.query(確認用SQL); 司書.create_book(ソロバン.calc(秘書.read(Accessのパス))); after = MySQL.query(確認用SQL); Assert.equal( (after.length == before.length + 1), true ); ```