The test kit also facilitates integration testing, allowing you to simulate the interaction between multiple players, servers, and the blockchain. You can:
Create multiple test clients: Instantiate TestClient objects for each player and server you want to simulate.
// Rust exampleuse race_test::TestClient;use race_core::types::ClientMode;// Create test clients for playersletmut alice =TestClient::player("Alice");letmut bob =TestClient::player("Bob");// Create test clients for servers (transactor and validators)letmut transactor =TestClient::transactor("Foo");letmut validator1 =TestClient::validator("Bar");letmut validator2 =TestClient::validator("Baz");
Set up the game environment: Create a test game account and initialize the game context and handler as in unit testing.
// Rust exampleuse race_test::TestGameAccountBuilder;use race_core::context::GameContext;use race_test::TestHandler;// Define your game's account data structure#[derive(BorshSerialize, BorshDeserialize)]structMyGameData {// ... game-specific data fields}// Create a test game accountlet game_account =TestGameAccountBuilder::default().add_player(&mut alice, 1000).add_player(&mut bob, 1000).set_transactor(&mut transactor).add_validator(&mut validator1).add_validator(&mut validator2).with_data(MyGameData { /* ... */ }).build();// Create the game contextletmut ctx =GameContext::try_new(&game_account).unwrap();// Initialize your game handler (replace MyGameHandler with your actual handler)letmut handler =TestHandler::<MyGameHandler>::init_state(&mut ctx, &game_account).unwrap();
Simulate game flow: Use the test clients to send events, interact with the game, and observe the overall game flow and interactions between components.
// Simulate game start eventlet event = ctx.gen_start_game_event();handler.handle_event(&mut ctx, &event).unwrap();// Loop to simulate game events and interactionswhileletSome(dispatch_event) = ctx.get_dispatch() {// Handle dispatched events (e.g., timeouts) handler.handle_dispatch_event(&mut ctx).unwrap();// Simulate player actions and server responses// ... (use test clients to send events and update context)// Handle events generated by clients and the updated context handler.handle_until_no_events(&mut ctx, vec![&mut alice, &mut bob, &mut transactor, &mut validator1, &mut validator2]).unwrap();}
Verify settlements: After the game concludes, verify that the generated settlements and asset distributions are correct and match the game outcome.
// After the game loop ends, verify settlementslet settles = ctx.get_settles().unwrap();// Assert that the settlements are correct based on the game outcome// ... (e.g., check if the winner received the pot, players' balances are updated)
Remember:
Adapt these examples to your specific game logic and testing needs.
The handle_until_no_events function is useful for simulating the event loop and handling events generated by clients and the updated context.
Use assertions to verify the expected game state, effects, and settlements throughout the simulation.
By following these steps and using the Race test kit effectively, you can perform comprehensive integration testing for your Race Protocol game bundles.
Integration Testing Example
WASM Bundle and Client-Side (Combined)
Here's an example of integration testing using the Race test kit to simulate a game flow with multiple players, involving both the WASM bundle and client-side code:
// Rust code for setting up the game environment and simulating server interactionsuse race_test::{TestClient, TestGameAccountBuilder, TestHandler};... (Set up game account, context, and handler) ...letmut server_client =TestClient::new(context.clone(), handler.clone());letmut player1_client =TestClient::new(context.clone(), handler.clone());letmut player2_client =TestClient::new(context, handler);// Simulate game flow with events from server and players... (Send events and interact with the game) ...// Assert the expected final state and settlementslet final_state = server_client.context().handler_state();let settlements = server_client.context().settlements();assert_eq!(final_state, expected_final_state);assert_eq!(settlements, expected_settlements);
// TypeScript code for simulating client interactionsimport { TestClient } from'@race-foundation/sdk-core';... (Connect to the game using AppClient or SubClient) ...// Simulate player actions and event exchangeawaitplayer1Client.submitEvent({ type:'joinGame',... });awaitplayer2Client.submitEvent({ type:'joinGame',... });awaitplayer1Client.submitEvent({ type:'playerMove',... });awaitplayer2Client.submitEvent({ type:'playerMove',... });// Observe game state updates and revealed information... (Handle events and update UI) ...
This combined example shows how to use the test kit to simulate interactions on both the server and client sides, allowing you to test the overall game flow and verify the final state and settlements.