Unity Test RunnerでPlayerPrefsが消える原因|DeleteAllに注意

確認環境

Unity
6000.3.8f1
対象
Unity Editor / Edit Mode・Play Modeテスト
検証OS
macOS 26.5.2 / Apple silicon Mac
関連Package
Unity Test Framework 1.6.4

結論

Unity Test Runnerは、PlayerPrefsをテスト専用の保存領域へ自動で隔離しません。

テストのSetUpやTearDownでPlayerPrefs.DeleteAll()を呼ぶと、その時点でUnity Editorが使用しているPlayerPrefsの全キーが削除されます。

テスト用データだけを初期化したい場合はDeleteAll()を使わず、テストが変更するキーだけを削除・保存・復元します。

Unity Test Runner自体を初めて使う場合は、先にUnity Test Runnerとは?基本と使い方を確認してください。

症状

今回確認した症状は次のとおりです。

  • Edit Modeテストの終了後、テストで直接使用していないPlayerPrefsまで消えていた
  • テスト自体はすべて成功していた
  • Consoleにも原因を示す例外は出ていなかった
  • テスト前後でPlayerPrefsを比較して初めて削除に気づいた

原因

Unity Test Runnerは保存先を切り替えない

Edit ModeテストやPlay Modeテストから通常のPlayerPrefs APIを呼ぶと、Unity Editorが現在使用しているPlayerPrefsへアクセスします。

Test RunnerがCompany Name、Product Name、保存先をテスト用へ自動変更する処理はありません。

PlayerPrefs.DeleteAll()は全キーを削除する

テストのSetUpとTearDownで、次の処理を実行していました。

[SetUp]
public void SetUp()
{
    PlayerPrefs.DeleteAll();
}

DeleteAll()は、このテストが使用するキーだけを削除する処理ではありません。同じPlayerPrefs領域にある次のような値も削除対象になります。

  • ゲーム進行状況
  • 音量や表示設定
  • チュートリアル完了状態
  • SDKや別機能が保存した値

確認方法

テストコード内で、まず次を検索します。

PlayerPrefs.DeleteAll()

見つかった場合は、SetUp、TearDown、テスト用helperなど、どこから呼ばれているか確認します。

テスト対象外の確認用キーを1つ用意し、テスト後も残っているか比較する方法も有効です。

PlayerPrefs.SetString("sentinel_key", "before-test");
PlayerPrefs.Save();

テスト終了後にこのキーが消えていれば、対象外のPlayerPrefsまで変更されています。

解決方法

DeleteAll()ではなく変更するキーだけを扱う

テストが専用キーだけを使用するなら、PlayerPrefs.DeleteKey()で対象キーだけを削除します。

private const string TestKey = "test_score";

[SetUp]
public void SetUp()
{
    PlayerPrefs.DeleteKey(TestKey);
}

[TearDown]
public void TearDown()
{
    PlayerPrefs.DeleteKey(TestKey);
}

元から存在するキーを変更する場合は復元する

ゲーム本体でも使用するキーをテストで変更する場合は、テスト前に次の情報を保存します。

  • キーが存在していたか
  • 値の型
  • 元の値

テスト終了時には、元から存在していたキーは元の値へ戻し、存在していなかったキーは削除します。

可能ならPlayerPrefsを直接テストしない

ゲームコードからPlayerPrefsを直接呼ばず、保存処理をinterfaceなどで分離する方法もあります。

テスト時にメモリ上の実装へ差し替えれば、実際のPlayerPrefsへ触れずにロジックを確認できます。

関連記事

Play Modeテスト終了時に実Saveファイルが更新される問題は、Unity Test RunnerでSaveが書き換わる原因と対策で説明しています。

参考資料