はじめに
2025年6月20日、Webアプリケーションのテストを自然言語で記述できるツール「kotoba」v0.0.1をリリースしました。この記事では、203個のパターンマッチングによる高速アサーション機能の実装と、段階的フォールバック戦略による6倍の性能改善について詳しく解説します。
kotoba とは
kotobaは、自然言語でWebテストを記述できるPythonツールです。PlaywrightとLLMを組み合わせて、以下のような日本語の指示でブラウザ操作を自動化できます。
「ログイン」ボタンをクリックして
メールアドレス欄に「test@example.com」を入力
パスワード欄に「password123」を入力
「送信」ボタンをクリック
「ログイン成功」というメッセージが表示されていることを確認
課題: LLM処理のボトルネック
自然言語テストツールの最大の課題は処理速度です。すべての指示をLLMで処理すると:
- 平均処理時間: 1.1-1.6秒/指示
- 原因: LLMの推論処理が必要
- 影響: 大規模なテストスイートで実行時間が膨大に
この課題を解決するため、頻出パターンを事前に定義し、LLMへの依存を最小限に抑える戦略を採用しました。
解決策: 段階的フォールバック戦略
1. アーキテクチャ設計
kotobaに以下の段階的処理フローを実装しました:
自然言語指示
↓
【Stage 1】アサーションパターンマッチング (< 1ms)
↓ (一致)
✅ アサーション実行
↓ (不一致)
【Stage 2】LLMによる一般アクション処理 (100-1000ms)
↓
🎯 ブラウザアクション実行
2. 25種類のアサーションタイプ
包括的なテスト検証のため、以下のアサーションタイプを実装:
class AssertionType(Enum):
# テキスト関連
TEXT_EXISTS = "text_exists"
TEXT_NOT_EXISTS = "text_not_exists"
TEXT_EQUALS = "text_equals"
TEXT_CONTAINS = "text_contains"
# 要素関連
ELEMENT_EXISTS = "element_exists"
ELEMENT_VISIBLE = "element_visible"
ELEMENT_ENABLED = "element_enabled"
# URL/タイトル関連
URL_CONTAINS = "url_contains"
TITLE_CONTAINS = "title_contains"
# フォーム関連
INPUT_VALUE_EQUALS = "input_value_equals"
CHECKBOX_CHECKED = "checkbox_checked"
# ... 他13種類
3. 203個のパターンマッチング実装
自然言語の多様性に対応するため、以下のカテゴリで203個のパターンを実装:
基本的な日本語パターン
# テキスト存在確認
(r"[「""]?(.+?)[」""]?が(?:表示されて|出て|見えて)?(?:いる|いること|いることを)(?:確認|チェック|検証)",
AssertionType.TEXT_EXISTS, "text"),
# 丁寧語対応
(r"[「""]?(.+?)[」""]?が(?:表示されて|出て|見えて)?(?:いる|いること|いることを)(?:確認|チェック|検証)(?:します|してください|お願いします)",
AssertionType.TEXT_EXISTS, "text"),
口語・疑問形パターン
# 関西弁
(r"[「""]?(.+?)[」""]?(?:が|って)(?:出てる|見える)(?:で|やん|やんか|わ|な)(?:?|\?)?",
AssertionType.TEXT_EXISTS, "text"),
# 疑問形
(r"[「""]?(.+?)[」""]?(?:は|が)(?:表示されて|見えて)(?:いますか|いるでしょうか|いるか)(?:?|\?)?",
AssertionType.TEXT_EXISTS, "text"),
英語・中国語パターン
# 英語
(r"(?:verify|check|confirm|assert)(?:\s+that)?\s+[\"'](.+?)[\"']\s+(?:is|exists?|appears?|is\s+(?:visible|displayed|present))",
AssertionType.TEXT_EXISTS, "text"),
# 中国語
(r"(?:验证|检查|确认|断言)[\"'""](.+?)[\"'""](?:存在|显示|出现)",
AssertionType.TEXT_EXISTS, "text"),
専門分野パターン
# IT・Web業界
(r"[「""]?(.+?)[」""]?(?:が|の)(?:レンダリング|描画|出力)(?:が|は)(?:正常|適切|問題なし)(?:か|かどうか)(?:確認|検証|チェック)",
AssertionType.TEXT_EXISTS, "text"),
# フォーム要素
(r"[「""]?(.+?)[」""]?(?:ボタン|button|Button|按钮|按鈕)(?:が|は)(?:表示|存在|クリック可能|押せる|有効)(?:になって|で|に)(?:いる|いること)(?:を|について)?(?:確認|検証|チェック)",
AssertionType.ELEMENT_EXISTS, "button"),
実装の技術的詳細
パターンマッチングエンジン
class AssertionPatternMatcher:
@classmethod
def parse(cls, instruction: str) -> Optional[Dict[str, Any]]:
for pattern, assertion_type, param_type in cls.PATTERNS:
match = re.search(pattern, instruction)
if match:
# 柔軟な引用符対応
text = match.groups()[0].strip()
text = text.strip('「」""''\'\'""')
return {
"type": assertion_type,
"expected": text,
"selector": None
}
return None # LLMフォールバック
アサーション実行エンジン
class AssertionExecutor:
async def execute(self, assertion: Assertion) -> AssertionResult:
start_time = time.time()
try:
if assertion.type == AssertionType.TEXT_EXISTS:
# 複数セレクター戦略で堅牢性確保
selectors = [
f"text={assertion.expected}",
f"text=*{assertion.expected}*",
f":has-text('{assertion.expected}')"
]
for selector in selectors:
elements = await self.page.query_selector_all(selector)
if elements:
return AssertionResult(passed=True, ...)
except Exception as e:
return AssertionResult(passed=False, error_message=str(e))
パフォーマンス改善結果
処理時間の劇的改善
| パターン数 | LLM利用率 | 平均処理時間 | 効率向上 |
|---|---|---|---|
| 54個 (初期) | 30% | 300ms | ベースライン |
| 130個 (中間) | 10% | 100ms | 3倍高速化 |
| 203個 (現在) | 5% | 50ms | 6倍高速化 |
| 500個 (目標) | 1% | 10ms | 30倍高速化 |
テスト成功率の向上
- 成功率: 100% (6/6テストケース)
- エラー処理: 堅牢なフォールバック機構
- 国際化対応: 日本語、英語、中国語
実際の使用例
YAML形式のテストケース
name: "アサーション機能テスト"
base_url: "https://example.com"
test_cases:
- name: "基本的なテキスト確認"
steps:
- instruction: "「Example Domain」が表示されていることを確認"
- instruction: "URLにexample.comが含まれていることをチェック"
- name: "口語表現での確認"
steps:
- instruction: "Example Domainって表示されてる?"
- instruction: "Example Domainが見えてますか?"
実行結果
{
"assertion_result": {
"type": "text_exists",
"passed": true,
"expected": "テキスト 'Example Domain' が1つ以上存在",
"actual": 1,
"execution_time_ms": 6.17
}
}
今後の展望
Phase 2: 機械学習支援パターン生成
- ログデータからの自動パターン抽出
- 使用頻度による動的最適化
Phase 3: 究極の高速化
- 500個以上のパターン実装
- 1ms台の処理速度実現
- コミュニティ貢献によるパターンDB構築
まとめ
kotobaのアサーション機能実装により、以下を達成しました:
- 6倍の高速化: 300ms → 50ms
- 203個のパターン: 多様な自然言語表現に対応
- 100%テスト成功率: 堅牢なエラーハンドリング
- 多言語対応: 日本語、英語、中国語
この取り組みは、自然言語処理とWebテスト自動化の融合において、新たな可能性を示しています。パターンマッチングとLLMを組み合わせることで、使いやすさと高速性を両立させることができました。
kotoba v0.0.1は2025年6月20日にリリースされ、オープンソースとして公開されています。今後も継続的な改善により、世界最高性能の自然言語テストツールを目指していきます。
GitHub: kotoba
リリース日: 2025年6月20日(v0.0.1)
技術スタック: Python, Playwright, LLM, Regex
