スキル一覧に戻る
nmnhut-it

bitzero-methodology

by nmnhut-it

0🍴 0📅 2026年1月20日
GitHubで見るManusで実行

SKILL.md


name: bitzero-methodology description: Strategies for exploring and testing tightly-coupled BitZero code. Use when code seems untestable, has singleton dependencies, or you need to understand complex game logic before writing tests.

BitZero Testing Methodology

Practical strategies for testing real BitZero game servers like escoba-server.

The Reality

BitZero code has heavy coupling:

  • 200+ getInstance() calls (singletons everywhere)
  • UserDAOImpl.getInstance() in every handler
  • MsgService.sendByUID() static calls
  • BitZeroServer.getInstance() for user management

Don't fight it. Use integration tests.

Testing Strategy

Level 1: Unit Test (Pure Methods)

For code with NO singleton calls in constructor:

// BasePlayer constructor is clean - unit testable
@Test
void basePlayer_ScoreCalculation() {
    BasePlayer player = new BasePlayer(1, false, "Test", 1, "", 1, 0, false, false, 1000L);

    player.getScore().put(SCORE_ENUM.ESCOBA, 2);
    player.getScore().put(SCORE_ENUM.MOST_CARD, 1);

    assertEquals(3, player.getTotalScore());
}

Level 2: Integration Test (Everything Else)

For code that uses singletons - just start the server:

class TableIntegrationTest extends IntegrationTestBase {

    @Test
    void tableService_IsInitialized() {
        // Server started by @BeforeAll - singletons ready
        TableServiceImpl service = TableServiceImpl.getInstance();
        assertNotNull(service);
    }

    @Test
    void tableConfig_IsLoaded() {
        assertNotNull(TableConst.TABLE_CONFIG);
        assertEquals(4, TableConst.TABLE_CONFIG.maxPlayerInTable);
    }
}

Integration Test Infrastructure

TestServer

public class TestServer {
    public void start() throws Exception {
        BitZeroServer server = BitZeroServer.getInstance();
        server.setClustered(false);
        server.start();
        waitForServerReady();
    }
}

IntegrationTestBase

public abstract class IntegrationTestBase {
    protected static TestServer testServer;

    @BeforeAll
    static void startTestServer() throws Exception {
        testServer = new TestServer();
        testServer.start();  // All singletons initialized!
    }

    protected TableServiceImpl getTableService() {
        return TableServiceImpl.getInstance();
    }
}

Codebase Exploration Strategy

Use MCP tools to understand dependencies before testing:

1. lookupClass("MyHandler")
   → See what it extends, what methods it has

2. getCallHierarchy("MyHandler", "handleClientRequest", callers=false)
   → See what singletons it calls

3. getTypeHierarchy("BaseClientRequestHandler")
   → Find the protected send() method (seam!)

4. lookupClass("BaseGame")
   → See constructor params (injection points)

What's Testable in BitZero

Pure Methods (Unit Test)

Look for methods with no external dependencies:

// In BasePlayer - pure calculation, easy to test
public int getTotalScore() {
    return this.score.entrySet().stream()
        .filter(e -> e.getKey() != SCORE_ENUM.TOTAL_SCORE)
        .map(Map.Entry::getValue)
        .reduce(0, Integer::sum);
}

public int countNumber7Cards() {
    int count = 0;
    for (int card7Id : GameConst.CARD_7_IDS) {
        if (this.listCardResult.contains(card7Id)) count++;
    }
    return count;
}

Singleton-Heavy Code (Integration Test)

When code uses UserDAOImpl.getInstance() or similar:

public class AccountIntegrationTest extends IntegrationTestBase {

    @Test
    void getUserData_ValidUser_ReturnsProfile() {
        // Server running, singletons initialized
        var service = TableServiceImpl.getInstance();
        var tables = service.getAvailableTables(1, 10);
        assertNotNull(tables);
    }
}

Finding What's Testable: Checklist

Look ForHow to FindTest Type
Clean constructorlookupClass → no getInstance() in constructorUnit test
Pure methodsNo getInstance(), no field access to singletonsUnit test
Singleton usagegetInstance() anywhereIntegration test
Static callsMsgService.sendByUID()Integration test

Escoba-Server Specific Patterns

What CAN Be Unit Tested

BasePlayer
├── Constructor: No singletons - CLEAN
├── Pure methods:
│   ├── getTotalScore() → unit test
│   ├── countNumber7Cards() → unit test
│   ├── check7Vang() → unit test
│   └── isStillOnline() → unit test
└── Singleton methods:
    ├── pack() → uses UserDAOImpl - integration test
    └── addGold() → uses ItemHandler - integration test

What NEEDS Integration Test

BaseTable
├── Constructor: Calls BitZeroServer.getInstance() - BLOCKED
└── All methods need integration test

TableServiceImpl
├── Singleton itself
└── All methods need integration test

Handlers
├── Use TableServiceImpl.getInstance()
├── Use UserDAOImpl.getInstance()
└── All need integration test

Test Double Patterns

StubPlayer (for unit tests)

// BasePlayer is already testable - just create normally
BasePlayer player = new BasePlayer(
    1, false, "TestPlayer", 1, "",
    1, 0, false, false, 1000L
);
player.setPlayerStatus(PLAYER_STATUS.PLAYING);
player.setListCardResult(List.of(24, 25, 26)); // three 7s

Practical Workflow

1. READ the code
   lookupClass, getMethodBody

2. CHECK the constructor
   - Has getInstance()? → Integration test
   - Clean? → Unit test possible

3. IDENTIFY pure methods
   - No getInstance() in method body
   - No static calls to singletons
   - Just works on instance fields

4. CHOOSE test type
   - Pure methods on clean class → Unit test
   - Everything else → Integration test

5. WRITE tests
   - Unit: Create object, call method, assert
   - Integration: Extend IntegrationTestBase, use real services

Key Principles

  1. Don't fight singletons - Use integration tests
  2. Unit test what's pure - Clean constructors, pure methods
  3. Start server once - Reuse across test class
  4. No mocking frameworks - Real server, real behavior
  5. Test what matters - Game logic, scoring, state transitions

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です