<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Testing on ROBOCO</title>
    <link>https://roboco.io/ja/tags/testing/</link>
    <description>Recent content in Testing on ROBOCO</description>
    <generator>Hugo</generator>
    <language>ja</language>
    <lastBuildDate>Sat, 10 Oct 2026 10:00:00 +0900</lastBuildDate>
    <atom:link href="https://roboco.io/ja/tags/testing/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>オープンソースプロジェクトから学ぶソフトウェアファクトリーのベストプラクティス（3/4）：証拠でふるいにかけるファクトリー</title>
      <link>https://roboco.io/ja/posts/software-factory-evidence-before-fix/</link>
      <pubDate>Sat, 10 Oct 2026 10:00:00 +0900</pubDate>
      <guid>https://roboco.io/ja/posts/software-factory-evidence-before-fix/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;「&lt;code&gt;USE_SYSTEM_BUN=1&lt;/code&gt;で通るテストは有効ではない（Your test is NOT VALID if it passes with &lt;code&gt;USE_SYSTEM_BUN=1&lt;/code&gt;）」 – Bun &lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;figure&gt;&lt;img src=&#34;https://roboco.io/posts/images/Dohyun.png&#34;&gt;&lt;figcaption&gt;&#xA;      &lt;h4&gt;チョン・ドヒョン - ROBOCO首席コンサルタント&lt;/h4&gt;&#xA;    &lt;/figcaption&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;この記事は、4回シリーズ「オープンソースプロジェクトから学ぶソフトウェアファクトリーのベストプラクティス」の第3回です。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;シリーズの構成&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://roboco.io/ja/posts/software-factory-best-practices-from-open-source/&#34;&gt;判定基準と12のリポジトリ：何をファクトリーと呼び、どこで動いているのか&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://roboco.io/ja/posts/software-factory-who-merges/&#34;&gt;誰がマージするのか：リスクに基づく委任と権限構造&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;証拠でふるいにかけるファクトリー：「修正前には失敗する」ことの証明（本記事）&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://roboco.io/ja/posts/software-factory-failures-into-rules/&#34;&gt;失敗をルールに：自己改善ループとその限界&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;冒頭の引用は、Bunリポジトリのエージェント向け指示にある一文です。&lt;code&gt;USE_SYSTEM_BUN=1&lt;/code&gt;は、修正する前の既存のBunリリースでテストを実行させる設定です。つまりこのルールは、「修正前のコードでも通るテストは何も証明しない」という意味です。&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://roboco.io/ja/posts/software-factory-who-merges/&#34;&gt;第2回&lt;/a&gt;では、マージ権限を誰に与えるかよりも、マージ前に何が確認されるよう強制するかが重要だとまとめました。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 今回はその確認の中身を扱います。エージェントはコードを素早く書きますが、常に通る無意味なテストや、実際より誇張した作業報告も簡単に作ります。そしてBunのエージェント&lt;code&gt;robobun&lt;/code&gt;が2026年9月の1か月間に作成したPRは2,313件です。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; この規模では、人がすべてのdiffを読むことはできません。そこでファクトリーは、人がコードを読む前にまず&lt;strong&gt;証拠&lt;/strong&gt;を見るようにしています。数値はこれまでの回と同じく、2026年10月10日にGitHub APIで取得した値です。&lt;/p&gt;&#xA;&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;観察した事例をまとめると、ファクトリーが求める証拠は三層です。問題が実際に存在することを示す再現、修正前には失敗し修正後には通るテスト、そして単体テストを超えた実際の動作の証拠です。&lt;/li&gt;&#xA;&lt;li&gt;そのうち3つのプロジェクトがそれぞれ異なる方法で実装した仕組みが、「修正前の失敗」の証明です。BunはPR本文に修正前の失敗ログを添付し、mastraはCIが新しいテストを修正前のコードに対して実行して失敗するかを確認し、観察したVercel AI SDKの修正PRは再現 → 失敗するテスト → 修正の順にコミットを積み上げていました。&lt;/li&gt;&#xA;&lt;li&gt;証拠は回避されることがあります。mastraでは修正前失敗ゲートの失敗ラベルが付いたままマージされたPRがあり、Astroでは「動作する」と確認された修正が意図と異なっていたため差し戻されました。証拠の仕組みは、マージ条件と結びついたとき、そして意図まで確認したときに効力を持つと私は考えています。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;1-三層の証拠&#34;&gt;1. 三層の証拠&lt;/h2&gt;&#xA;&lt;p&gt;観察したプロジェクトがエージェントに求める証拠を私の基準でまとめると、3種類になります。&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;証拠の種類&lt;/th&gt;&#xA;          &lt;th&gt;問いかける質問&lt;/th&gt;&#xA;          &lt;th&gt;代表的な仕組み&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;再現&lt;/td&gt;&#xA;          &lt;td&gt;問題は実際に存在するか&lt;/td&gt;&#xA;          &lt;td&gt;Vercel AI SDKの再現PR、Astroの再現ステップ&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;修正前の失敗&lt;/td&gt;&#xA;          &lt;td&gt;このテストは本当にその問題を捉えるか&lt;/td&gt;&#xA;          &lt;td&gt;Bunの証拠ブロック、mastraの修正前コードテストゲート、Vercel AI SDKのコミット順序&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;実際の動作&lt;/td&gt;&#xA;          &lt;td&gt;単体テストの外でも動作するか&lt;/td&gt;&#xA;          &lt;td&gt;OpenClawの動作証拠ラベル、OpenHandsのライブE2E、Astroのプレビューリリース&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;私は、この三層が順番に積み重なるものだと考えています。再現がなければ何を直したのかがわからず、修正前の失敗がなければテストが何を証明しているのかがわかりません。そして、単体テストが通っても実際の環境では壊れることがある、というのが三層目が必要な理由です。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;2-まず再現する&#34;&gt;2. まず再現する&lt;/h2&gt;&#xA;&lt;p&gt;Vercel AI SDKのファクトリーは、バグのIssueを受け取るとまず再現を試みます。再現に成功すると、サンプルファイルと再現記録ファイル（&lt;code&gt;reproduction-replay.json&lt;/code&gt;）を含むドラフトPRを作成します。観察したIssue #22412の再現PRは、確認後にクローズされました。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; 再現結果はラベルとして残ります。&lt;code&gt;task-bug-reproduction-success&lt;/code&gt;、&lt;code&gt;-cannot-reproduce&lt;/code&gt;、&lt;code&gt;-issue-invalid&lt;/code&gt;、&lt;code&gt;-out-of-scope&lt;/code&gt;といったラベルがあり、サポートしているバージョン（v5、v6）ごとに結果を個別に記録します。&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; この結果によって次のステップが分岐するように見えますが、ファクトリーの内部ルールはリポジトリの外にあるため、確認できませんでした。&lt;/p&gt;&#xA;&lt;p&gt;Astroのファクトリーは、再現 → 診断 → 意図の検証 → 修正の順に作業します。各ステップには止まるためのルールがあります。再現用サーバーの起動に2回失敗すると、あきらめてレポートを書きます。診断の確信度が低ければ、そこで止まります。意図の検証ステップで「意図された動作」と判定すると、修正しません。&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; 確信度が低いときには、コードを直す代わりに失敗するテストと&lt;code&gt;// TRIAGE:&lt;/code&gt;コメントだけを残す経路もあります。人が引き継げるように、手がかりだけを残すのです。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
