Skip to main content

Testing On-Chain Randomness

Testing randomness requires special attention to ensure fair distribution and proper behavior.

Setting Up Tests

Testing Initial State

Verify players start with zero points:

Testing Randomness Distribution

Verify both outcomes occur with reasonable frequency:

Running Tests

# Run all tests
npm test

# Run with verbose output
npm test -- --verbose

# Run specific test file
npm test sandbox-test/main.ava.js

Test Best Practices

1. Test Edge Cases

test('handles minimum points correctly', async (t) => {
// Ensure points don't go below 0
const points = await contract.view('points_of', {
player: account.accountId
});
t.true(points >= 0);
});

2. Mock Randomness for Unit Tests

For deterministic testing, consider mocking:

#[cfg(test)]
fn mock_random_seed() -> [u8; 32] {
[42; 32] // Fixed seed for testing
}

3. Integration Testing

Test the full flow with multiple accounts:

test('multiple players maintain separate scores', async (t) => {
const { root, contract } = t.context.accounts;
const alice = await root.createSubAccount('alice');

// Play as root
await root.call(contract, 'flip_coin', { player_guess: 'heads' });

// Play as alice
await alice.call(contract, 'flip_coin', { player_guess: 'tails' });

// Check separate scores
const rootPoints = await contract.view('points_of', { player: root.accountId });
const alicePoints = await contract.view('points_of', { player: alice.accountId });

t.not(rootPoints, alicePoints); // Different players, different scores
});

With tests confirming our randomness works correctly, let's explore advanced patterns for more complex use cases.