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セッションの回数(大規模モデルゲートウェイへの呼び出し回数)が削減され、ユースケースファイルの生成速度が全体的に向上します。ConversationSummaryBufferMemory
主に「要約」情報の抽出に使用され、要件と設計ドキュメントの内容を大規模モデルに渡す前に要約します。

ベクターデータベース: 同社の既存のベクターデータベーステスト環境である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="あなたは人間と会話するチャットボットです。"
)、# 永続的なシステムプロンプト
メッセージプレースホルダー(
変数名="チャット履歴"
)、# メモリが保存される場所。
HumanMessagePromptTemplate.from_template( "{human_input}"
)、# 人間の入力が挿入される場所
]
)
memory = 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)
コンテンツ = docs[0].page_content
# ベクトルクエリの情報を使用して、大規模モデルのテストケースを生成します prompt_template = "ソフトウェアテスト開発の専門家として、製品要件技術設計の {input_prompt} の関連情報({content})に基づいて、Markdown 形式でテストケースを出力してください。テストケーステンプレートは次のとおりです: {empty_case}"
プロンプト = プロンプトテンプレート(
input_variables=["入力プロンプト", "コンテンツ", "空ケース"],
テンプレート=プロンプトテンプレート
)
llm = LLMFactory.get_openai_factory().get_chat_llm()
チェーン = LLMChain(
llm=llm、
prompt=プロンプト、
詳細=True
)
output_raw = チェーン.invoke(
{'input_prompt': input_prompt, 'content': content, 'empty_case': 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. テストケースの生成は、テスト効率向上のほんの一部に過ぎません。将来的には、大規模なモデルを日々のテストプロセスに適用していく必要があります。現在検討されているアイデアとしては、差分コードとサーバーログの分析による欠陥の自動検出や、モデル駆動型テストとナレッジグラフを組み合わせた自動テストなどが挙げられます。