壁紙アプリの更新を段階公開に載せた翌朝、Play Console のトラック一覧をぼんやり眺めておりました。Internal、Closed、Open、Production——私にとっては毎回同じ順で通るだけの並びです。
ところが同じ画面が、新しくアカウントを作った方には別の意味を持ちます。Production のページが、押せない状態でそこに置かれているのです。
先にお伝えしておきます。私自身のアカウントは2023年11月13日より前に作ったもので、この要件の対象外です。ですから「12人を集めるのに苦労しました」という体験談は書けません。書けるのは、同じ閉鎖テストトラックを段階公開のために毎回通している側から見た、日数の数え方と記録の残し方です。
本番のボタンが押せないのは、アプリの出来とは別の話です
Google Play では、2023年11月13日より後に作られた個人開発者アカウントに対して、公開前のテストが求められます。閉鎖テストで 12人以上のテスターが連続14日以上 opt-in している状態を作ってから、Play Console のダッシュボードで本番アクセスを申請するという流れです。
条件を満たすまで、Production と事前登録(Pre-registration)のページは無効のまま置かれます。組織アカウントと、2023年11月13日より前に作られた個人アカウントは対象外です。そしてこの要件はアプリごとにかかります。要件の原文は App testing requirements for new personal developer accounts(Play Console ヘルプ) にあります。
最初のうち、私はストアで詰まったときの原因をいつも「アプリの直し方」の側から読もうとしすぎました。結果は芳しくありませんでした。ビルドは通っているのにボタンが灰色のまま、という場面では、直す先がコードではないのです。
審査を通す作業と、配布の権利を開ける作業は、別々の進行として持ちます。 同じ画面に並んでいるので混ざりやすいのですが、片方を急いでも、もう片方は前に進みません。
数えられているのは人数ではなく、連続して入っていた日数です
ここがいちばん取り違えやすいところです。数えられているのは「これまでに参加してくれた人の総数」ではありません。申請する時点から数えて、直前の14日間ずっと opt-in していた人が何人いるかです。
公式のよくある質問には、14日に届かないうちに抜けた方は数に入らないこと、いったん抜けて入り直した場合は14日を連続で満たす必要があることが、はっきり書かれています。つまり離脱は「1人減る」ではなく、その方の日数が振り出しに戻るという意味を持ちます。
だとすれば、ちょうど12人で走らせる設計は薄氷です。1人が通知を切ってアプリを消し、テストから抜けた——それだけで申請日が2週間先へずれてしまいます。招待は12人ぴったりではなく、抜ける方がいても残る人数で組んでおくほうが穏やかです。
もうひとつ、申請後に「opt-in が12人に届いていない」または「テスト期間中の関与が不十分」と判断されると、テストの継続を求められることがあります。人数の形だけを整えても、そこは通り抜けられません。
トラックの順番を間違えると、14日のカウントが始まりません
トラックには役割の違いがあり、開く順番も決まっています。
| トラック | 役割 | 使えるようになる条件 |
|---|---|---|
| Internal testing | 身内の少人数へ即座に配る | 条件なし。アプリ設定の完了前でも配れます |
| Closed testing | 自分が選んだ相手に配る。14日を数える場所 | アプリ設定の完了 |
| Open testing | 誰でも参加できる公開テスト | 本番アクセスの取得後 |
| Production | Google Play での一般公開 | 閉鎖テストの条件を満たして申請し、承認されること |
Open testing を先に開いて人を集めようとしても、そのページは本番アクセスを得るまで開きません。順番は Internal → Closed → 申請 → Production です。
実務としては、次の順で進めると迷いが減ります。
- Internal testing に上げて、自分と身近な方の端末で起動と主要画面だけ確かめます
- アプリ設定(ストア掲載情報・データセーフティ・年齢区分など)を完了させます
- Closed testing のトラックを作り、テスターリストか opt-in リンクを配ります
- 参加日を記録し、そこから14日を数え始めます
- 届いた声に返事をして、直したものを閉鎖テストへ上げ直します
- ダッシュボードから本番アクセスを申請します
Rork から書き出したプロジェクトを EAS で上げているなら、トラックの取り違えは設定側で防げます。
{
"submit": {
"internal": {
"android": {
"track": "internal"
}
},
"closed": {
"android": {
"track": "alpha"
}
}
}
}# 身内へ即座に配る(アプリ設定の完了前でも通ります)
eas build -p android --profile production
eas submit -p android --profile internal --latest
# 14日を数える場へ上げる(アプリ設定の完了後)
eas submit -p android --profile closed --latesttrack に指定できるのは internal / alpha / beta / production です。閉鎖テストに独自の名前を付けたトラックを使っている場合は、alpha へ上げてから Play Console 側でそのトラックへ昇格させるかたちになります。アップロード後は、必ず Console でどのトラックに入ったかを目で確かめてください。ここで版番号がぶつかると別の足止めが起きますので、「Version code 1 has already been used」の番号は、app.json と EAS のどちらが持っているか も先に読んでおくと安全です。
申請フォームが聞いてくるのは、14日間に何をしたかです
本番アクセスの申請は、ダッシュボードの「Apply for production」から始まります。フォームは3つのセクションに分かれていて、聞かれることは事前に分かっています。
| セクション | 聞かれること |
|---|---|
| About your closed test | テスターを集めるのがどれくらい大変だったか/テスターが全機能を触ったか/その使い方が本番の利用者の想定と合っていたか、違いがあればその内容/集まった声の要約と、どうやって集めたか |
| About your app/game | 対象とする利用者層(できるだけ具体的に)/アプリが利用者に与える価値/初年度のインストール数の見込み |
| About your production readiness | 閉鎖テストで分かったことをもとに何を変えたか/本番に出せると判断した根拠 |
この一覧を先に読むと、14日間の過ごし方が変わります。テスターが全機能を触ったか、どんな声が来て何を変えたか——これは、あとから思い出して書けるものではないのです。
14日間は待機ではなく、フォームの答えを作る期間です。 私はこの読み替えを、いちばん効く準備だと感じています。
細かいところで、各セクションは「Next」を押さないと保存されません。書きかけで離れると消えます。認証が必要なアプリなら、動作するテスト用の資格情報を Console に入れておいてください。申請後の審査は通常7日以内に結果が返ります。
閉鎖テストで見えるのは実機の挙動までで、ストアに出したときの姿とは別物です。その差の埋め方は Rork Companion で動いた画面を、私はまだ完成とは呼びません に書きました。
14日間の記録は、1枚のファイルと1本のスクリプトで足ります
記録は凝らなくてよいと思っています。テスターごとに参加日と離脱日、届いた声の一行要約と収集経路、直した内容と上げ直したバージョン。この3種類が残っていれば、フォームの空欄はほとんど埋まります。
参加日だけは手で数えると間違えますので、小さなスクリプトに任せています。
"""Play の閉鎖テストで「連続14日以上 opt-in している人数」を数えます。
使い方: python3 closed_test_status.py testers.csv --as-of 2026-09-09
CSV の列: tester,opted_in,opted_out (opted_out が空なら現在も参加中)
"""
import argparse, csv, sys
from datetime import date, timedelta
REQUIRED_DAYS = 14
REQUIRED_TESTERS = 12
def parse_day(value):
if not value or not value.strip():
return None
return date.fromisoformat(value.strip())
def main():
ap = argparse.ArgumentParser()
ap.add_argument("csv_path")
ap.add_argument("--as-of", default=date.today().isoformat())
args = ap.parse_args()
as_of = parse_day(args.as_of)
active, dropped = [], []
with open(args.csv_path, newline="", encoding="utf-8") as fh:
for row in csv.DictReader(fh):
joined, left = parse_day(row["opted_in"]), parse_day(row["opted_out"])
if joined is None or joined > as_of:
continue # まだ参加していない方は数えません
if left is not None and left <= as_of:
dropped.append((row["tester"], (left - joined).days))
continue # 抜けた方は連続日数が振り出しに戻ります
active.append((row["tester"], (as_of - joined).days,
joined + timedelta(days=REQUIRED_DAYS)))
qualified = [t for t in active if t[1] >= REQUIRED_DAYS]
print(f"基準日: {as_of} 参加中: {len(active)}人 離脱: {len(dropped)}人")
print(f"連続{REQUIRED_DAYS}日以上: {len(qualified)}人 / 必要 {REQUIRED_TESTERS}人")
for name, days, _ in sorted(active, key=lambda t: t[1], reverse=True):
mark = "OK " if days >= REQUIRED_DAYS else " "
print(f" {mark}{name:<12} 連続 {days:>3}日")
for name, days in dropped:
print(f" OUT {name:<12} {days}日で離脱(再参加しても14日は数え直しです)")
if len(qualified) >= REQUIRED_TESTERS:
print("→ 本番アクセスの申請条件を満たしています")
return 0
eligible_dates = sorted(t[2] for t in active)
if len(eligible_dates) < REQUIRED_TESTERS:
need = REQUIRED_TESTERS - len(eligible_dates)
print(f"→ 参加中が {len(active)}人。あと {need}人を招待しないと条件に届きません")
return 1
print(f"→ 誰も抜けなければ {eligible_dates[REQUIRED_TESTERS - 1]} に条件を満たします")
return 1
if __name__ == "__main__":
sys.exit(main())13人を招待し、そのうち1人が9日で抜けた状態を入れて実行すると、こう返ります。
基準日: 2026-09-09 参加中: 12人 離脱: 1人
連続14日以上: 7人 / 必要 12人
OK t01 連続 20日
OK t02 連続 20日
OK t03 連続 19日
OK t04 連続 18日
OK t05 連続 18日
OK t06 連続 16日
OK t07 連続 15日
t08 連続 12日
t09 連続 8日
t10 連続 7日
t11 連続 6日
t12 連続 6日
OUT t13 9日で離脱(再参加しても14日は数え直しです)
→ 誰も抜けなければ 2026-09-17 に条件を満たします最後の一行が、申請日の予定を立てる材料になります。人数の表示だけを見ていると「12人いるから出せる」と読んでしまうところを、日数で見れば足りていないことが分かります。
なお、公開の期日が絡む話はこの要件だけではありません。更新を出す予定があるなら target API 36 の8月31日は、更新を出す人と出さない人で意味が違います のような締切も、同じカレンダーに並べておくほうが安全です。
今日やっておくこと
テスターに招待を配る前に、メモを1枚だけ作ってください。見出しは3つで、申請フォームのセクション名をそのまま使います。「閉鎖テストについて」「アプリについて」「本番に出せる根拠」。中身は空欄のままで構いません。
14日後、その空欄を埋められるかどうかで、申請が一度で終わるか、もう2週間伸びるかが分かれます。個人開発では、伸びた2週間を取り戻す手立てがないのです。だから私は、書く場所を先に作っておくやり方を続けています。
お読みいただきありがとうございました。同じ画面の前で足止めされている方の、次の一歩が短くなれば嬉しく思います。