BigQuery上の自動テスト開発のススメ
データ基盤ひとりAdventCalendarの17日目の記事になります。
データ基盤に関連した内容について学んだことを@takegue がまとめていきます。

内容については随時加筆/修正等を行なっていく予定です。
修正等の指摘ありましたらご連絡いただけると幸いです。


データウェアハウシングにおいて、整合性や信頼性を高め保ち続けることは
そこから派生する分析やデータアプリケーションの質に直結することからも重要な課題のひとつでります。
特にデータハウスでは異なる複数のデータソースまたはそれらから派生したデータについて実施をおこなっていく必要があります。

一般に開発が大規模であればあるほど、整合性や信頼性を保つためのコストが高くなります。
特にBigQueryのようなカラムナ型ストレージを採用するシステムでは、RDBMSに用意されているユニーク制約や外部参照制約といったレコードに制約を課すことができません。このためテーブルの結合というSQLの簡単な操作でも思わぬ形で整合性を崩す恐れがあります。
また大規模データ処理ではRDBMSでは扱わないような大量のイベントデータを時系列で大量に取り扱う必要があります。このようなイベントデータは、発生源であるアプリケーションのデータウェアハウジングの外部のシステムからの影響を受けやすくなります。加えて、プロダクト開発において、アプリケーションが変化しないということは起こりえないため、データの特性自体も中長期で見た場合に不安定です。
したがって、BigQuery上に格納されるデータは、システム外部から送られてくるデータの不安定さの影響を受けやすい。上流から稀に発生する不整合をもたらすデータによって分析の信頼性を損なうリスクを抱え続けます。ということが言えると思います。

この不安定さはデータにだけでなく分析のために記述するSQLコードにも及びます。
データの不安定さは、データに対する暗黙的な属人的知識を生み、これに基づいて行われるデータの前処理や後処理はゆれを産みやすくなります。

BigQueryではSQLの再利用性を高めるために論理テーブル(ビュー)を構築することが可能です。
しかしながら、論理テーブルを多用した依存関係はさながら砂の城のようなもので、大規模化するつれ開発・運用が困難になり、上流の些細なバグにより下流の依存の整合性が簡単に崩れるやすくなります。これは論理テーブルの代わりに物理テーブルを生成するジョブを発行しても同様です。
また時間経過と共に起きるデータの特性の変化によりコードが陳腐化する自体も起きるため、固定化されたSQLは時間差でバグを生む要因となります。

このような観点から、データおよびそこから生じる分析やデータ機能のため整合性や信頼性を保持するため持続可能な検証方法を取り入れていく必要があります。

自動テストはこのような方法の一つとして開発でもよく取り入れられているプラクティスであり
テスト駆動開発による開発は、システムに対して高い変動制と持続可能性をもたらし
開発チームの規模に対する一定のスケールメリットをもたらします。

データストレージに対する自動テスト


RDBMSを利用したアプリケーション開発ではRDBMSに対する操作を含めた
アプリケーションロジックに対して検証を行うため

  • モッキング(Mocking)による仮想データベースを用いた検証
  • 初期データを投入したテスト用DBを用いた検証

の検証方法を用いることによって、RDBMSを利用したアプリケーションコードのテストが行われるのが一般的でしょう。

両者の使い分けは、前者はアプリケーションコードのみで実現されサービスを介さないため高速であるため、多くの反復検証を必要とするユニットテストで多く利用されます。
後者は、一回の試行に時間を必要とするものの実際に動作するシステムを利用した信頼性の高い検証が行えるため、結合テストの用途で利用されます。

BigQuery上でのテスト方法を考えた場合SQLコード自身のテストはSQLが汎用プログラミング言語ではないことから
前者の方法では実現が難しく、後者のテスト用のDBを用意した検証が利用されることが多いです。

次の記事ではPythonを利用してBigQuery上にテスト用のデータセットおよびテーブルを構築し
そのデータに対して対象のSQLを発行し、その結果をPythonコードを中心に検証を行なっています。