@prefix schema: <https://schema.org/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ks: <https://comcomponent.com/vocab/> .

<https://comcomponent.com/blog/characterization-test-legacy-refactoring/#article>
    schema:about <https://comcomponent.com/knowledge/characterization-test/>, <https://comcomponent.com/knowledge/legacy-code/> ;
    schema:mentions <https://comcomponent.com/knowledge/method-extraction-refactoring/>, <https://comcomponent.com/knowledge/refactoring/>, <https://comcomponent.com/knowledge/golden-master-testing/>, <https://comcomponent.com/knowledge/regression-risk/>, <https://comcomponent.com/knowledge/golden-master-diff-review/>, <https://comcomponent.com/knowledge/mixed-commit-antipattern/>, <https://comcomponent.com/knowledge/seam/>, <https://comcomponent.com/knowledge/dependency-injection-seam/>, <https://comcomponent.com/knowledge/internals-visible-to/>, <https://comcomponent.com/knowledge/output-normalization/>, <https://comcomponent.com/knowledge/dotnet-test-command/>, <https://comcomponent.com/knowledge/vstest-console/> .

<https://comcomponent.com/knowledge/characterization-test/> a skos:Concept ;
    skos:prefLabel "特性化テスト"@ja ;
    skos:definition "正しい挙動ではなく、いまのコードが実際にどう振る舞っているかという「現在の挙動」を記録するテスト。"@ja ;
    skos:altLabel "characterization test" ;
    ks:shouldPrecede <https://comcomponent.com/knowledge/method-extraction-refactoring/> ;
    ks:shouldPrecede <https://comcomponent.com/knowledge/refactoring/> ;
    ks:mitigates <https://comcomponent.com/knowledge/regression-risk/> ;
    ks:recommendedFor <https://comcomponent.com/knowledge/legacy-code/> .

<https://comcomponent.com/knowledge/legacy-code/> a skos:Concept ;
    skos:prefLabel "レガシーコード"@ja ;
    skos:definition "Michael Feathersが「単に古いコード」ではなく「テストのないコード」として定義した、変更結果を確かめる手段を欠いたコード。"@ja ;
    skos:altLabel "Legacy Code" .

<https://comcomponent.com/knowledge/method-extraction-refactoring/> a skos:Concept ;
    skos:prefLabel "メソッド抽出"@ja ;
    skos:definition "UIイベントハンドラーなどに直書きされたロジックを、外部依存を引数として受け取る別メソッドへ切り出すリファクタリング手法。"@ja ;
    skos:altLabel "Extract Method" ;
    skos:altLabel "メソッドの抽出"@ja ;
    ks:implements <https://comcomponent.com/knowledge/seam/> .

<https://comcomponent.com/knowledge/refactoring/> a skos:Concept ;
    skos:prefLabel "リファクタリング"@ja ;
    skos:definition "挙動を変えることなく、コードを保守・理解・拡張しやすくするために構造を変更するプロセス。"@ja ;
    skos:altLabel "Refactoring" ;
    ks:incompatibleWith <https://comcomponent.com/knowledge/mixed-commit-antipattern/> .

<https://comcomponent.com/knowledge/golden-master-testing/> a skos:Concept ;
    skos:prefLabel "ゴールデンマスター法"@ja ;
    skos:definition "変更対象の出力をそのまま期待値ファイル(ゴールデンマスター)として保存し、以後のコード変更のたびに出力と期待値の差分がゼロであることを確認する特性化テストの具体的な手法。"@ja ;
    skos:altLabel "承認テスト"@ja ;
    skos:altLabel "approval testing" ;
    skos:altLabel "スナップショットテスト"@ja ;
    skos:altLabel "snapshot testing" ;
    skos:altLabel "Golden Master Testing" ;
    skos:broader <https://comcomponent.com/knowledge/characterization-test/> ;
    ks:implements <https://comcomponent.com/knowledge/characterization-test/> ;
    ks:recommendedFor <https://comcomponent.com/knowledge/legacy-code/> .

<https://comcomponent.com/knowledge/regression-risk/> a skos:Concept ;
    skos:prefLabel "退行リスク"@ja ;
    skos:definition "変更によって意図しない挙動変化(退行)が入り込み、それに気づけないリスク。"@ja ;
    skos:altLabel "Regression Risk" .

<https://comcomponent.com/knowledge/golden-master-diff-review/> a skos:Concept ;
    skos:prefLabel "期待値の差分レビュー"@ja ;
    skos:definition "ゴールデンマスターを更新する前に、変更前後の出力差分を目視でレビューし、意図した変更だけが含まれることを確認する運用手順。"@ja ;
    skos:altLabel "Diff Review" ;
    ks:mitigates <https://comcomponent.com/knowledge/regression-risk/> .

<https://comcomponent.com/knowledge/mixed-commit-antipattern/> a skos:Concept ;
    skos:prefLabel "リファクタリングと機能追加の混在コミット"@ja ;
    skos:definition "挙動を変えない変更(リファクタリング)と挙動を変える変更(機能追加・バグ修正)を同じコミットに混ぜてしまう運用上のアンチパターン。"@ja ;
    skos:altLabel "Mixed Commit" .

<https://comcomponent.com/knowledge/seam/> a skos:Concept ;
    skos:prefLabel "継ぎ目(seam)"@ja ;
    skos:definition "Michael Feathersの言う、テストコードから挙動を差し替え・観測できる場所。"@ja ;
    skos:altLabel "シーム"@ja ;
    skos:altLabel "Seam" ;
    ks:recommendedFor <https://comcomponent.com/knowledge/legacy-code/> .

<https://comcomponent.com/knowledge/dependency-injection-seam/> a skos:Concept ;
    skos:prefLabel "インターフェース差し込み"@ja ;
    skos:definition "DateTime.Nowやファイルパスの直接参照など、引数化だけでは済まない依存をインターフェースで包み、テスト側で差し替え可能にする手法。"@ja ;
    skos:altLabel "Extract Interface" ;
    skos:altLabel "依存の抽象化"@ja ;
    ks:implements <https://comcomponent.com/knowledge/seam/> .

<https://comcomponent.com/knowledge/internals-visible-to/> a skos:Concept ;
    skos:prefLabel "InternalsVisibleTo属性"@ja ;
    skos:definition "通常は同一アセンブリ内でしか見えないinternal/protected internal/private protectedの型・メンバーを、指定したフレンドアセンブリ(テストプロジェクトなど)から見えるようにする.NETの属性。"@ja ;
    skos:altLabel "InternalsVisibleToAttribute" .

<https://comcomponent.com/knowledge/output-normalization/> a skos:Concept ;
    skos:prefLabel "出力の正規化"@ja ;
    skos:definition "印字日時・処理時間・GUID・自動採番など実行のたびに変わる非決定的な値を、比較前に固定文字列へ置換する前処理。"@ja ;
    skos:altLabel "Output Normalization" .

<https://comcomponent.com/knowledge/dotnet-test-command/> a skos:Concept ;
    skos:prefLabel "dotnet testコマンド"@ja ;
    skos:definition ".NET SDKに含まれる標準のテスト実行コマンド。"@ja ;
    skos:altLabel "dotnet test" .

<https://comcomponent.com/knowledge/vstest-console/> a skos:Concept ;
    skos:prefLabel "vstest.console.exe"@ja ;
    skos:definition "ビルド済みのテストDLLを直接指定して実行できる、Developer Command Promptから使うコマンドラインツール。"@ja ;
    skos:altLabel "VSTest.Console.exe" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/characterization-test/> ;
    rdf:predicate ks:shouldPrecede ;
    rdf:object <https://comcomponent.com/knowledge/method-extraction-refactoring/> ;
    schema:description "変更する箇所の周辺だけ現在の挙動を特性化テストで固定してから、継ぎ目を作るための最小限のリファクタリング(メソッド抽出)を行う"@ja ;
    ks:evidence <https://learn.microsoft.com/visualstudio/ide/reference/refactoring-extract-inline> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/characterization-test/> ;
    rdf:predicate ks:shouldPrecede ;
    rdf:object <https://comcomponent.com/knowledge/refactoring/> ;
    schema:description "テスト可能な構造になったら、特性化テストという安全網の内側で本来のリファクタリングや機能追加に着手する"@ja ;
    ks:evidence <https://learn.microsoft.com/visualstudio/ide/refactoring-in-visual-studio> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/golden-master-testing/> ;
    rdf:predicate ks:implements ;
    rdf:object <https://comcomponent.com/knowledge/characterization-test/> ;
    schema:description "ゴールデンマスター法は、出力をそのまま期待値ファイルとして保存し差分比較することで特性化テストを実現する具体的な手法である"@ja ;
    ks:evidence <https://github.com/approvals/ApprovalTests.Net> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/golden-master-testing/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/legacy-code/> ;
    schema:description "出力の単位が大きいレガシーコードには、ゴールデンマスター法が最も費用対効果の高い特性化テストであるというのが本記事の推奨である"@ja ;
    ks:evidence <https://github.com/approvals/ApprovalTests.Net> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/legacy-code/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/regression-risk/> ;
    schema:description "テストのないレガシーコードでは、変更結果が正しいかを確かめる手段がないため、意図しない挙動変化(退行)に気づけないリスクがある"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/testing/unit-testing-best-practices> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/characterization-test/> ;
    rdf:predicate ks:mitigates ;
    rdf:object <https://comcomponent.com/knowledge/regression-risk/> ;
    schema:description "特性化テストは現在の挙動を期待値として固定し、変更のたびに差分比較することで退行リスクを軽減する"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/testing/unit-testing-best-practices> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/golden-master-diff-review/> ;
    rdf:predicate ks:mitigates ;
    rdf:object <https://comcomponent.com/knowledge/regression-risk/> ;
    schema:description "期待値を更新する前に差分を1行1行目視でレビューすることで、意図しない退行をそのまま正として取り込んでしまう事故のリスクを軽減する(人手のレビューのため見落としが残り得る)"@ja ;
    ks:evidence <https://github.com/approvals/ApprovalTests.Net> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/mixed-commit-antipattern/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/regression-risk/> ;
    schema:description "リファクタリングと機能追加を同じコミットに混ぜると、差分が出たときに意図した変更か退行かを切り分けられなくなる"@ja ;
    ks:evidence <https://learn.microsoft.com/visualstudio/ide/refactoring-in-visual-studio> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/method-extraction-refactoring/> ;
    rdf:predicate ks:implements ;
    rdf:object <https://comcomponent.com/knowledge/seam/> ;
    schema:description "メソッド抽出は、計算部分だけを切り出し外部依存を引数化することで、テストから挙動を観測できる継ぎ目を作る代表的な手段である"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/testing/unit-testing-best-practices> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dependency-injection-seam/> ;
    rdf:predicate ks:implements ;
    rdf:object <https://comcomponent.com/knowledge/seam/> ;
    schema:description "引数化だけでは済まない規模の依存には、インターフェースで包んで差し替え可能にすることで継ぎ目を作る"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/testing/unit-testing-best-practices> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/seam/> ;
    rdf:predicate ks:configuredBy ;
    rdf:object <https://comcomponent.com/knowledge/internals-visible-to/> ;
    schema:description "internalのままテストしたい継ぎ目は、本体側にInternalsVisibleTo属性を1行加えることでテストプロジェクトから見えるように構成できる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.internalsvisibletoattribute> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/refactoring/> ;
    rdf:predicate ks:incompatibleWith ;
    rdf:object <https://comcomponent.com/knowledge/mixed-commit-antipattern/> ;
    schema:description "差分ゼロが合格条件のリファクタリングと、意図した差分だけが合格条件の機能追加は合格条件が正反対のため、同じコミットに混ぜてはならない"@ja ;
    ks:evidence <https://learn.microsoft.com/visualstudio/ide/refactoring-in-visual-studio> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/golden-master-testing/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/output-normalization/> ;
    schema:description "印字日時やGUIDなど非決定的な値が出力に混ざる場合、比較の前に出力の正規化を挟まないと毎回差分が出てしまう"@ja ;
    ks:evidence <https://github.com/approvals/ApprovalTests.Net> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/regression-risk/> ;
    rdf:predicate ks:verifiedBy ;
    rdf:object <https://comcomponent.com/knowledge/dotnet-test-command/> ;
    schema:description "退行の有無はコミット前にdotnet testを実行し、差分ゼロであることを確認して判断できる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/tools/dotnet-test> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/regression-risk/> ;
    rdf:predicate ks:verifiedBy ;
    rdf:object <https://comcomponent.com/knowledge/vstest-console/> ;
    schema:description "旧形式のcsprojが混在しdotnet testが動かない場合は、vstest.console.exeでビルド済みテストDLLを直接実行して退行の有無を確認できる"@ja ;
    ks:evidence <https://learn.microsoft.com/visualstudio/test/vstest-console-options> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/characterization-test/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/legacy-code/> ;
    schema:description "仕様書がなくテストもないレガシーコードに安全に手を入れるには、まず特性化テストで現在の挙動を固定することが本記事の推奨である"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/testing/unit-testing-best-practices> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/seam/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/legacy-code/> ;
    schema:description "UIイベントハンドラー直書きや現在時刻への直接依存のように、テストを差し込めない構造のレガシーコードには継ぎ目を作ることが本記事の推奨である"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/testing/unit-testing-best-practices> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dotnet-test-command/> ;
    rdf:predicate ks:incompatibleWith ;
    rdf:object <https://comcomponent.com/knowledge/legacy-code/> ;
    schema:description "旧形式(非SDKスタイル)のcsprojが混ざったレガシーなソリューションでは、dotnet testコマンドが期待どおりに動かないことがある"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/tools/dotnet-test> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/vstest-console/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/legacy-code/> ;
    schema:description "dotnet testが期待どおりに動かないレガシーなソリューションでは、vstest.console.exeを使う方法が代替手段として推奨される"@ja ;
    ks:evidence <https://learn.microsoft.com/visualstudio/test/vstest-console-options> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .
