Clean Codeの著者であるUncle BobがXで投稿した記事(link)を見つけました。この投稿には数千のリポストがついています。彼はもうコードを読まないと言っています。そうです、開発者はコードを書くよりも読む方がはるかに多いので、コードは読みやすくあるべきだという本を書いた人です。
ではUncle Bobの方法とは?AIエージェントが書いたコードを読む代わりに、そのコードに対して大量のテストを書くようにエージェントに依頼するのです。
もちろん賛成する人もいれば、反対する人もいます。コードを読まなければ、所有権の意味は曖昧になります。しかし、すべてのコードを読めば生産性のほとんどを失うことになります。ここで判断したり、私の「価値ある」意見を提供したりはできません。私はこの投稿を書くことにしました(あまり書きません)が、それはここやあちらで繰り返し出てくるトピックがあったからです。
今、多くの議論はAIの検証についてです。もちろん、生物学やバイオインフォマティクスにおける検証はソフトウェアエンジニアリングにおける検証とは異なりますが、何らかの価値ある重複があると感じています。
スレッドやリポストでは、Uncle Bobを含むプログラマーがエージェントを抑えるために使用するさまざまなテストが言及されています。深く掘り下げると、バイオインフォマティシャンとして予想していたよりもはるかに大きなテストの世界が開かれました。
正確性
- ユニットテスト – 個々の関数や小さなコード単位を分離してチェックします。ロジック、エラーハンドリング、エッジケースをチェックします。最もよく知られたタイプのソフトウェアテストです。
- 統合テスト – 別々のモジュールが正しく連携して動作することを確認します(例:APIがデータベースと通信する場合)。
-
機能テスト – ソフトウェアがブラックボックス、要件の観点から、意図した通りに動作することを検証します。ソフトウェアに入力データを与え、出力を確認します。たとえば、新しいSNVコールパイプラインを書いた場合、参照に対してシーケンシングデータを入力し、パイプラインが既知のSNVを必要な感度と特異性で出力するかどうかを確認します。
機能テストには知っておく価値のある一般的なサブタイプもあります:- スモークテスト – 基本的な機能が動作することを迅速に確認します。例:デフォルトパラメータでソフトウェアを実行する。
- 回帰テスト – 最近の更新が既存の機能を破壊しなかったことを確認します。
- ユーザー受け入れテスト(UAT) – 実際のユーザーがニーズが満たされていることを確認するかどうかをチェックします。「実際のユーザー」とは、GitHubからツールをダウンロードするコミュニティ科学者や、早期アクセスや共同開発プログラムのパートナーを意味します。ここでの他のカテゴリと同様に、UATには独自のサブワールドがあります:アルファテスト、ベータテスト、ビジネス価値の検証、ソフトウェアが契約基準を満たしていることの検証、規制要件(GDPR、HIPAA、FDA)を満たしていることの検証。注:名前が似ていますが、受け入れテスト(下記)は開発者/QAによって実行されるのに対し、UATは実際のユーザーによって実際の使用ケースで実行されます。
受け入れテスト / Gherkinテスト – 完全な機能が構築されたビジネス要件を満たしていることを確認します。Gherkinテストは構造化された、人間が読みやすい形式(Given/When/Then)で書かれるため、非エンジニアもコードを読まずに意図された動作を確認できます:Givenはコンテキストを説明し、Whenはソフトウェアによってキャプチャされた特定のユーザーアクションまたはイベントを説明し、Thenは期待される結果を説明します。
-
Truth-set / ゴールデンデータセットテスト – Uncle Bobからのものではなく、私のバイオインフォマティクスの経験からのものです。バイオインフォマティクス、特に臨床バイオインフォマティクスでは、主にウェットラボで起こっていることに関連する複数の理由で合成テストを生成することが困難です。そのため、生物学はグラウンドトゥルースサンプルに大きく依存しています。別記事で書く価値がありますが、NGS(私の主な専門分野)では、MDIC SRS Report: Somatic Variant Reference Samples for NGSが良い概要リソースです。2019年のもので少し古いかもしれません — 確かに多くのリンク切れがあります — が、私は最近説明されているサンプルで作業しました。いくつかのクラスの参照材料が説明されています:
- 合成DNA – 事前に定義された遺伝的変異を持つ合成DNA配列が、高度に特徴付けられたDNAに追加されます。
- ゲノムDNA – 特徴付けられた変異を持つDNA材料。
- Cell-free DNA – 血液サンプルから抽出されたDNA材料。
- ヒト細胞株 – 広範囲に研究された不死化細胞株。Genome In A Bottle (GIAB)がおそらく最も有名で、高品質なDNAでシステムを評価するために使用できます。
- 組織 / ホルマリン固定パラフィン包埋(FFPE) – 多くの臨床サンプルは、主に組織学的理由でFFPEとして保存されます。しかし、NGSでは、FFPEサンプル調製プロセスは高度に有害で、非常に断片化され、損傷したDNAをもたらします。しかし、FFPEの臨床的重要性により、多くのバイオインフォマティクスNGSワークフローはFFPEサンプルでテストされる必要があります。
- 直交検証テスト – 私のバイオインフォマティクスのもう一つの入力。市販の特徴付けられたサンプルが利用できない場合、検証のもう一つの方法は、2つ以上の独立した方法に対して出力をチェックすることです。例:NGS、サンガーシーケンシング、ロングリード技術、光学マッピング、細胞遺伝学など。
ストレス下での堅牢性
-
パフォーマンステスト – 予想されるまたはピーク負荷の下での応答時間、スループット、リソース使用量を測定し、回帰をキャッチします。これは特にクラウドコンピューティングで重要で、コンピューティングリソースを過大評価すると過払いになり、過小評価するとシステムクラッシュにつながる可能性があります。バイオインフォマティシャンとして最も関連性が高いと思うサブタイプ:
- 負荷テスト – パフォーマンステストの最もシンプルな形式:システム(私の場合、バイオインフォマティクスパイプライン)が通常の負荷の下でどのように動作するか?例:会社が1日あたり100のNGSサンプルを処理し、1サンプルあたり約10Mリードペアを処理することを期待します。
- ストレステスト – 通常の負荷を超えた場合、システムはどのように動作するか?ある日10,000サンプルを処理する必要がある場合、または各サンプルに100Mリードがある場合はどうか?
- 耐久テスト – システムを極端な、高負荷、またはエッジケースの条件に押し上げ、実際にどこで壊れるかを見つけます。100Mリードサンプルでパイプラインは壊れるか?200Mリードサンプルでは?
これらのテストのコストに関する注意事項(FinOps — 最近学んだ新しい用語の1つ):クラウド環境では、あまりにも多くのシナリオをテストすると高価になり、長時間気づかれずに実行される停止したプロセスを見逃すことも高価になる可能性があります。ローカルHPCユーザーやDevOpsチームも、ノードに過負荷をかけ、他のジョブに長いキューを引き起こすとかなり怒る可能性があります。
厳密性チェック(テスト自体のテスト)
- ミューテーションテスト – 意図的にコードに小さなバグを導入し、既存のテストスイートがそれらをキャッチするかどうかを確認します — たとえば、定数値を置き換えたり、決定ロジックを変更したり、コード構造をスキップしたりします。テストがまだパスする場合、スイートは十分に厳密ではありません。
- テストカバレッジ – コードベースの何パーセントが実際にテストによって実行されているかを測定し、未テストの領域にフラグを立てます。もちろん、テストの品質はカバレッジ数自体よりも重要です。
- 再現性 / 決定性テスト – スレッドにはありませんでしたが、バイオインフォマティクスとAIの両方で重要だと感じています。確率論的アプローチを使用する場合、出力が安定しているかどうかを確認するために、入力を数回テストする必要があります。AI/MLは本質的に確率論的であり、バイオインフォマティクスはAI/MLを明示的に使用しない場合でも、サンプリングやその他の確率論的技術を含む可能性があります。
変動のもう一つの原因は、ソフトウェアまたはパッケージのバージョンを切り替えることです — マイナーバージョンアップデートでも結果は劇的に変わる可能性があります。臨床検査のためのCLIA/CAP/CLEP規制では、ソフトウェア変更時の再評価が必要です。
非機能的およびシステム的チェック
- セキュリティテスト – 機能的な正確性ではなく脆弱性を探します:機密データは安全か、ユーザーパーミッションは期待通りに動作するか、システムはコードインジェクションから保護されているか?
-
アーキテクチャチェック – コードが定義されたアーキテクチャ境界と依存関係ルールを尊重していることを自動的に検証します:すべてのモジュールが意図した通りに接続されているか、命名規則が守られているか、パッケージの使用が一貫しているか(例:同じPythonプロジェクトで同じ目的のために
osとpathlibの両方を使用していないか)、依存関係グラフがサイクルを避けているか? -
品質メトリクス – メンテナンス性をヒントする一般的なコードヘルスインジケータ(循環的複雑度、依存関係構造、モジュールサイズ)。いくつかの興味深いもの:
- 欠陥密度 – 1,000行のコードあたりに見つかったバグの数。
- 欠陥逃避率 – テストに対して本番で見つかったバグの割合。
- 欠陥解決時間 – バグを修正するのに必要な時間。
GoogleのDORA(DevOps Research and Assessment)グループは、関連するが異なるメトリクスのセットを提案しています。ソフトウェアテスト品質メトリクスがリリース前にソフトウェアの成功を予測しようとするのに対し、DORAメトリクスはコードが本番に到達した後のソフトウェアデリバリーパフォーマンスを評価します。DORAはメトリクスをスループットと安定性にグループ化します:
スループット
- リードタイム – コミットされた変更を本番に持ち込むのに必要な時間。
- デプロイ頻度 – 所定の期間の本番リリース数。
- 失敗したデプロイ回復時間 – 欠陥解決時間の鏡像ですが、本番で測定されます。私にとって、これはスループットと安定性の両方にまたがります。
安定性
- 変更失敗率 – 欠陥逃避率の兄弟:本番に到達した後に即座の介入を必要とするデプロイ/リリースの割合。
- デプロイ手戻り率 – 本番インシデントによってトリガーされた、計画外だった本番リリースの割合。
探索的正確性
- プロパティテスト – 特定の入出力ペアをチェックする代わりに、コードが常に満たさなければならない一般的な不変条件を定義し、それらを破ろうとする多様な入力を多数生成します。
私にとって、プロパティテストは上記の「正確性」セクションのユニット/統合/機能テストに似ていると感じます。主なマインドセットのシフトは、関数がどのような正確な出力を生成するべきかではなく、どのようなプロパティを持つべきかを考えることです。たとえば、DNAモチーフを見つける関数をテストしているとします。ユニットテストでは、エッジケースを考えます:モチーフを含むDNA断片と、含まない断片。プロパティテストでは、不変条件を定義します:入力DNAにモチーフが含まれている場合、関数はその座標を返します。含まれていない場合、-1を返します。次に、このルールに従ってランダムなDNA/モチーフペアを生成し、関数が何回壊れるかを見ます。
プロセスとヒューマンレイヤー
- QA手順 – ユーザー/製品の観点からソフトウェアをチェックする、より広範で、しばしば手動の品質ワークフロー。
- 生成された成果物レビュー – コードの周囲でエージェントが生成するドキュメント、設定、ダイアグラムをレビューし、正確性の別のプロキシとして — 成果物の健全性チェックの一種。
私はこれらのテストをすべて使用したわけではなく、これらのすべてが典型的なバイオインフォマティクスパイプラインに属するかどうかも確信がありません — ただし、バイオインフォマティクスは常にソフトウェアエンジニアリングの実践と収束しようとしています。それでも、これらの概念に精通することは、ソフトウェアチームとAIコーディングエージェントの両方と協力するために非常に価値があると思います。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.