Appearance
Appearance
PlayerModel
s, PlayerAction
s and Tick
s. Take a look at the Getting Started section if you need a refresher..NET unit tests are good for testing your game's features for functional correctness. Metaplay provides some additional helpers and frameworks on top of NUnit to make it easier to test game-specific features in addition to classic unit testing.
You can implement test cases that trigger player actions against player models to ensure that the game works as expected. Your tests can also interact with the game configs system to model difficult scenarios beyond the default state of a new player.
The unit tests are standalone tests and do not need the game server running. This allows running the tests rapidly for fast iteration. To run tests against a running game server, take a look at the Advanced System Testing page.
Here's an overview of how the .NET unit tests should look in your Backend/
directory when created:
Backend The game-specific backend directory
├── SharedCode Backend C# project for shared code files
├── SharedCode.Tests Unit tests for the SharedCode project
├── Server Game-specific server C# project
├── Server.Tests Unit tests for Server project
├── MyProject-Server.sln Solution file for the backend (optional)
├── ...
Special Naming!
Use the exact same name for the directory, i.e., Backend/SharedCode.Tests
. For now, the Metaplay integration tests assume that your test projects are found in either Backend/SharedCode.Tests/
or Backend/Server.Tests/
directory. Otherwise, the tests will not be included in our integration test suite.
To get started, you need to create a new C# test project where your tests are placed.
The easiest way to do this is to copy the test project from the Idler sample, in MetaplaySamples/Idler/Backend/SharedCode.Tests
. Copy this into your project in the directory Backend/SharedCode.Tests/
.
The project structure in Idler's SharedCode.Tests
looks like this:
Backend Game-specific backend directory
├── SharedCode.Tests Shared code test C# project
├ ├── SharedCode.Tests.csproj The C# project file
├ ├── SetupFixture.cs One-time global setup fixture, initializes Metaplay
├ ├── PlayerActionTests.cs Examples for testing PlayerActions, PlayerModel and GameConfigs
The project in SharedCode.Tests
is intended to cover game logic-related functionality as it only references the SharedCode
C# project of your game project. The Server.Tests
is intended to target the game server project. This difference is only by convention and you don't need to follow it.
Optionally, you may add the newly created C# project to your IDE, for example to Visual Studio's solution file, like MyGame-Server.sln
.
While developing the tests, it's fastest to iterate on the tests by running them locally. You can do this just like with any other NUnit tests:
# Run the tests in the directory
Backend/SharedCode.Tests$ dotnet test
Optionally, you can only run a specific test or subset of tests with --filter
which runs all test cases containing the given string in their name:
Backend/SharedCode.Tests$ dotnet test --filter MyTestCase
To run the tests in your CI pipeline, take a look at Integration Testing.
Tests are mostly written as any other NUnit-based tests, but Metaplay offers some helpers for convenience.
To initialize Metaplay, you should have the following one-time setup fixture in your project:
using Metaplay.Cloud.Application;
[SetUpFixture]
public class TestSetUp
{
[OneTimeSetUp]
public void SetUp()
{
// Initialize for tests & set working directory to project root.
TestHelper.SetupForTests();
}
}
This initializes the Metaplay SDK and ensures that your working directory is in the root of the C# project (e.g., Backend/SharedCode.Tests/
) to help reliably load files, such as game config archives, from disk regardless of which environment is running the tests.
The Idler sample contains a complete implementation in MetaplaySamples/Idler/Backend/SharedCode.Tests/SetupFixture.cs
.
Below is a simplified example showing how you can test your game logic in unit tests. You can do this by creating a player model and then executing your player actions against it. You should also validate the player model state before and after to ensure the expected change happened.
[TestFixture]
public class MyTests
{
// Example test case to run PlayerActions against a created PlayerModel
[Test]
public void TestPlayerActions()
{
// Create initial player model to run action against. It also initializes
// the game configs from an on-disk archive file. See Idler sample for how
// the method implementation should look like.
PlayerModel playerModel = CreatePlayerModel();
// The WordPress producer should initially be on level 1
Assert.AreEqual(1, playerModel.Producers[wordPressId].Level);
// Run the PlayerUpgradeProducer action against the model, expect a success result
Assert.AreEqual(ActionResult.Success, ExecuteAction(playerModel, new PlayerUpgradeProducer(wordPressId)));
// Check that the WordPress producer level is now 2
Assert.AreEqual(2, playerModel.Producers[wordPressId].Level);
}
}
A lot of the setup is ignored here for simplicity. In practice, it's easiest to get started by just modifying the SharedCode.Tests/PlayerActionTests.cs
copied from the Idler sample to target the logic of your game.
For more information on how to use NUnit, take a look at Unit testing C# with NUnit and .NET Core.
To help better understand how to run your unit tests as part of Metaplay's integration tests in the CI, take a look at Integration Testing.
Also, check out Advanced System Testing to learn how to implement more complicated testing scenarios, including executing tests against a running game server from the outside.