HUOXIU

大規模モデルの応用:Langchainに基づくテストケース生成

ケース生成の実践的な結果

私たちのチームの日々の業務において、テスト手法の継続的な最適化とテスト効率の向上は常に重要な課題です。最近では、大規模モデルを用いたテストケース生成の検討と実践に取り組んでおり、その強力な自然言語処理能力を活用することで、より包括的で高品質なテストケースを自動生成することを目指しています。

現在、当社ではJoyCoder を広く導入しています。関連する要件や設計ドキュメントをJoyCoderにコピーしてテストケースを生成することができますが、使用にあたっては以下のような問題点があります。

1) ドキュメントのコピーと貼り付け、プロンプトの作成、結果のコピー、テストケースの保存など、複数の手動ステップが依然として必要です。

2) 応答時間が長く、結果が不安定になる: 要件または設計ドキュメントが大きい場合、プロンプトが長くなりすぎたり、トークン制限を超えたりすることがあります。

そこで、Langchain同社の既存プラットフォームをベースに、テストケースを自動的、迅速かつ安定的に生成できる方法を検討したところ、以下の結果が得られました。

JoyCoderの使用Langchainの自社開発に基づく
生成時間(詳細なドキュメントを含むプロジェクトの場合) • 約10~20分。複数の手動操作が必要です。(最初に「ご提供いただいた要件ドキュメントに基づき、Markdown形式のテストケース例を以下に示します。ドキュメントが長いため、一般的なテストケーステンプレートを提供します。各ステップは実際のニーズに合わせて調整できます。」というプロンプトが表示されます。) • コンテンツが多すぎる場合は、「デフォルトのトークン上限に達しました」、「原因不明のエラー:リクエストがタイムアウトしました。サーバーの過負荷が原因の可能性があります」などのエラーが発生します。入力するコンテンツの適切な量を判断するには、手動による介入が必要です。 • 約5分で自動生成(サマリーからすべてのテストポイントを生成した後、ベクトル検索を使用してさらに洗練されたテストケースを生成します)。 • コンテンツが多すぎる場合は、大規模モデルに提供する前に、トークンテキストに基づいてセグメント化できます。
生成時間(一般的な小規模なニーズの場合)差はわずか1〜5分です。
正確さプロンプトの内容に応じて違いはわずかですが、独自のソリューションを開発するときに最適化されたプロンプトを固める方が簡単です。

LangChain とは、大規模言語モデル (LLM) に基づいてアプリケーションを構築するためのオープンソース フレームワークです。LLM は、膨大な量のデータで事前トレーニングされた大規模なディープラーニング モデルであり、質問に答えたり、テキストベースのプロンプトに基づいて画像を作成したりするなど、ユーザーのクエリに対する応答を生成できます。LangChain は、モデルによって生成される情報のカスタマイズ性、精度、関連性を向上させるためのさまざまなツールと抽象化を提供します。たとえば、開発者は LangChain コンポーネントを使用して、新しいプロンプト チェーンを構築したり、既存のテンプレートをカスタマイズしたりできます。LangChain には、LLM が再トレーニングなしで新しいデータセットにアクセスできるようにするコンポーネントも含まれています。

2. 詳細な紹介

1. Langchainベースのテストケース生成スキーム

プランアドバンテージ欠点適用可能なシナリオ
オプション 1: すべての製品要件と R&D 設計ドキュメントを大規模モデルに提供して、ユースケースを自動的に生成します。テストケースの内容は比較的正確である大きなドキュメントはサポートされていないため、トークンの制限を超える可能性があります。一般的な要件と設計
オプション 2:すべての製品要件と R&D 設計ドキュメントを要約し、その要約情報を大規模モデルに提供してユースケースを自動的に生成します。サマリーが生成された後は、トークンの問題を心配する必要はありません。ユースケースは不正確で、ほとんどが一般的なポイントで構成されています。大規模な需要と設計
オプション 3: すべての製品要件と R&D 設計ドキュメントをベクター データベースに保存し、類似のコンテンツを検索して特定の部品のテスト ケースを自動的に生成します。ユースケースはより焦点が絞られており、トークンの問題を心配する必要はありません。包括的なユースケースセットではない要件と設計の特定の部分のみのユースケース生成

3 つのソリューションはそれぞれ使用例が異なり、それぞれの利点と欠点が補完し合うことができるため、私は 3 つの方法すべてを実装し、必要に応じて誰でも使用できるようにしています。

2. 実装の詳細

2.1 全体的なプロセス





2.2 技術的な詳細

PDFコンテンツの解析: Langchainは、CSV、JSON、HTML、PDFなど、様々なファイル形式の解析をサポートしています。PDFに関しては様々なライブラリが利用可能ですが、私は包括的な機能と高速な処理速度を理由にPyMuPDFを選択しました。



ファイル分割:過剰なデータ入力によって応答時間が長くなったり、大規模なモデルでトークン制限を超えたりすることを防ぐために、Langchain のテキスト分割ツールを使用してファイルを小さなテキストのリストに分割します。



メモリ使用量:ほとんどのLLMモデルにはセッションインターフェースがあります。このインターフェースを使用して大規模モデルの機能を呼び出すと、各呼び出しが新しいセッションを構成します。大規模モデルと複数ターンの会話をする際に、毎回前のコンテキストを繰り返すことなく行うには、以前の会話内容を記憶するメモリが必要です。メモリはそのようなモジュールであり、開発者がアプリケーションの「メモリ」を迅速に構築するのに役立ちます。この例では、LangchainのConversationBufferMemoryとConversationSummaryBufferMemoryを使用してこれを実装し、要件と設計ドキュメントをメモリに直接保存しました。これにより、大規模モデルとのQ&Aセッションの回数(大規模モデルゲートウェイへの呼び出し回数)が削減され、ユースケースファイルの生成速度が向上します。Conversation Summary BufferMemoryは主に「要約」情報を抽出するために使用されます。要件と設計ドキュメントの内容を要約し、大規模モデルに渡します。



ベクターデータベース:同社の既存のベクターデータベーステスト環境であるVearchを利用してファイルを保存しました。データテーブルを作成する際には、ベクターデータベースの検索モデルとそのパラメータを理解する必要があります。現在、IVFPQ、HNSW、GPU、IVFFLAT、BINARYIVF、FLATの6種類がサポートされています(詳細な違いとパラメータについては、こちらのリンクをご覧ください)。現在は、より基本的な量子化インデックスであるIVFFLATを選択しました。データ量が膨大になった場合やグラフデータ処理が必要な場合は、さらなる最適化が実装されます。さらに、Langchainは便利なVearchストレージとクエリメソッドも提供しています。



2.3 コードフレームワークと部分的なコードデモンストレーション

コードフレームワーク:





コード例:

 def case_gen(prd_file_path, tdd_file_path, input_prompt, case_name):
「」
テストケース生成方法のパラメータ:
prd_file_path - prd ファイルへのパス、tdd_file_path - 技術設計ドキュメントへのパス、case_name - 生成するテスト ケースの名前。
# 要件と設計関連のドキュメントを解析します。出力はドキュメントのリストです。prd_file = PDFParse(prd_file_path).load_pymupdf_split()
tdd_file = PDFParse(tdd_file_path).load_pymupdf_split()
empty_case = FilePath.read_file(FilePath.empty_case)
# 要件と設計関連のドキュメントを LLM メモリ情報としてメモリに設定します prompt = ChatPromptTemplate.from_messages(
[
システムメッセージ(
content="あなたは人間と会話するチャットボットです。"
)、# 永続的なシステムプロンプト
メッセージプレースホルダー(
変数名="チャット履歴"
)、# メモリが保存される場所。
ヒューマンメッセージプロンプトテンプレート.from_template(
「{人間の入力}」
)、# 人間の入力が挿入される場所
]
)
メモリ = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
prd_file内のprdの場合:
memory.save_context({"input": prd.page_content}, {"output": "これは要件ドキュメントです。テストケースは後で生成されます。"})
tdd_file内のtddの場合:
memory.save_context({"input": tdd.page_content}, {"output": "これは技術設計文書です。テストケースは後で生成されます。"})
# テストケースを生成するためにモデルサイズを増やす llm = LLMFactory.get_openai_factory().get_chat_llm()
human_input = "ソフトウェアテストおよび開発の専門家として、上記の製品要件と技術設計情報に基づいて、Markdown形式でテストケースを出力してください。" + input_prompt + "。テストケーステンプレートは" + empty_caseです。
チェーン = LLMChain(
llm=llm、
prompt=プロンプト、
詳細=True、
メモリ = メモリ、
)
output_raw = chain.invoke({'human_input': human_input})
# 出力テストケースの内容をMarkdown形式で保存します。file_path = FilePath.out_file + case_name + ".md"
open(file_path, 'w') をファイルとして実行します:
file.write(output_raw.get('text'))
 def case_gen_by_vector(prd_file_path, tdd_file_path, input_prompt, table_name, case_name):
「」
非常に大きなテキスト ファイルを扱う場合、トークンの不足を防ぐために、ベクター データベースを使用してコンテンツの特定の部分を取得し、ローカライズされたテスト ケースを生成することで、より正確な詳細が得られます。
パラメータ:
`prd_file_path` - PRD ファイルへのパス。`tdd_file_path` - 技術設計ドキュメントへのパス。`table_name` - ベクトル データベース内のテーブル名。異なるビジネス機能ごとに個別に保存され、通常はビジネス機能の一意の英語の略語が使用されます。`case_name` - 生成するテスト ケースの名前。
# 要件と設計関連のドキュメントを解析します。出力はドキュメントのリストです。prd_file = PDFParse(prd_file_path).load_pymupdf_split()
tdd_file = PDFParse(tdd_file_path).load_pymupdf_split()
empty_case = FilePath.read_file(FilePath.empty_case)
# ドキュメントをベクトルデータベースに保存する docs = prd_file + tdd_file
埋め込みモデル = LLMFactory.get_openai_factory().get_embedding()
router_url = ConfigParse(FilePath.config_file_path).get_vearch_router_server()
vearch_cluster = Vearch.from_documents(
ドキュメント、
埋め込みモデル、
path_or_url=ルーターのURL、
db_name="y_test_qa",
テーブル名=テーブル名、
フラグ=1、
)
# ベクトルデータベースから関連コンテンツを検索する docs = vearch_cluster.similarity_search(query=input_prompt, k=1)
content = docs[0].page_content # ベクトルクエリ情報を使用して大規模モデルのテストケースを生成します prompt_template = "ソフトウェアテスト開発の専門家として、製品要件技術設計の{input_prompt}の関連情報に基づいて、マークダウン形式でテストケースを出力してください: {content}。テストケーステンプレートは次のとおりです: {empty_case}"
プロンプト = プロンプトテンプレート(
input_variables=["入力プロンプト", "コンテンツ", "空ケース"],
テンプレート=プロンプトテンプレート)
llm = LLMFactory.get_openai_factory().get_chat_llm()
チェーン = LLMChain(
llm=llm、
prompt=プロンプト、
詳細=True
)
output_raw = チェーン.invoke(
{'input_prompt': 入力プロンプト、'content': コンテンツ、'empty_case': 空ケース})
# 出力テストケースの内容をMarkdown形式で保存します。file_path = FilePath.out_file + case_name + ".md"
open(file_path, 'w') をファイルとして実行します:
file.write(output_raw.get('text'))



3つの効果のデモンストレーション

3.1 要件/プロジェクトへの実践的適用の効果

生成されたテストケースが本当にテストケース設計の時間を節約できるかどうかは、誰にとっても重要な関心事です。そこで、小さな要件をランダムに抽出して実験を行いました。この要件のPRDドキュメントの総語数は2363語、設計ドキュメントの総語数は158語(その大部分はフローチャート)でした。実際のテストケース設計プロセスにおける効率向上は50%に達する可能性があります。

大規模モデルを使用してテストケースを自動的に生成する利点と欠点:

利点:

テストケースを包括的かつ迅速に論理的に分割することで、テスト分析による要件と設計の理解を支援します。 テストケースの作成時間を短縮し、手作業では内容の確認と詳細の調整のみが必要となります。 •テストケースの内容がより包括的かつ充実することで、テストケースレビュー時に補足すべきポイント数が減り、テスト漏れを効果的に防止します。 テスターが機能の一部のみをテストする責任がある場合、ベクターデータベース検索を通じて特定の機能の生成に集中することもできます。

デメリット:

複雑なフローチャートを理解していない場合、テキストによる説明が限られていると、生成されるコンテンツが不正確になる可能性があります。 経験豊富なテスターに​​とって、テストケースの自動生成方法は好みの方法と異なる場合があり、調整や適応が必要になることがあります。



4つの未解決の問題とフォローアップ計画

1. PDF内のフローチャート(画像形式)について、テキスト抽出と認識を実装しました(langchainのPDF関連メソッドはOCR認識をサポートしています)。今後の課題としては、グラフコンテンツの解析と取得のためのより適切な手法を見つけることです。2 .テストケースの生成は、テスト効率向上のほんの一部に過ぎません。今後の課題としては、大規模なモデルを日常的なテストプロセスに適用することなどが挙げられます。現在、差分コードとサーバーログの分析による欠陥の自動検出や、ナレッジグラフと組み合わせたモデル駆動型テストに基づく自動テストなどの構想があります。