Godot Mono and tests

In my previous post, I mentioned about using C# for Godot Mono. However, recently I found that, due to MonoDevelop is inactive, it causes my personal project not able to be built. As a result, I have to change the build tool to dotnet CLI. This can be set through

Godot (Mono) > Editor > Editor Settings > Mono > Builds > Build Tool

Besides that, I also changed the External Editor from MonoDevelop to Visual Studio Code. Visual Studio Code is nice for the C# project. It has autocompletion and able to find function definition and function references.

Previously, because I was using MonoDevelop, the Nuget packages (similar to npm packages) is managed by MonoDevelop, which I can add new packages through GUI. But now, I migrate the project to dotnet CLI, there is no more GUI. Luckily, dotnet allows to add Nuget packages to my existing project. For example,

dotnet add package MathNet.Spatial
dotnet add package MathNet.Numerics
dotnet add package NewtonSoft.Json

This will update the .csproj file. NOTE: This csproj file can be generated by adding a C# script through Godot Mono.

Tests

The advantages of using C# comparing to GD script (Godot script) are

  1. inheritance
  2. lambda syntax
  3. tests!

I was using FluentAssertions and Machine.Specifications previously on MonoDevelop, by creating a library project (.dll). Then run the command for the tests. However, after migrating to dotnet, I failed to run the tests. I tried several solutions.

Dotnet official websites mentioned about xUnit and NUnit. I tried both, but I failed to make both work. I failed to run the tests with dotnet test.

At the end, I use back FluentAssertions and Machine.Specifications.

Firstly, add the two packages to the existing project, not as a separate project.

dotnet add package FluentAssertions
dotnet add package Machine.Specifications
dotnet add package Machine.Specifications.Runner.Console

The Machine.Specifications.Runner.Console is important. I found that both xUnit and NUnit have runner console packages as well. Probably I can run the tests without dotnet test for both solutions.

After adding the packages, then I run a script to invoke the tests.

#!/bin/sh

PROJECT_NAME=MyProject
export MONO_PATH=./.mono/assemblies/Debug
CMD="mono $HOME/.nuget/packages/machine.specifications.runner.console/1.0.0/tools/mspec.exe"
TARGET=".mono/temp/bin/Debug/${PROJECT_NAME}.dll"

if (( "$#" > 0 )) ; then
    $CMD $TARGET -i "$@"
else
    $CMD $TARGET
fi

Export MONO_PATH because it contains GodotSharp.dll and GodotSharpEditor.dll. GodotSharp.dll is necessary as our C# source code inherits the classes from Godot.

The shell script above will invoke mono mspec.exe, where mspec.exe locates at .nuget in our home directory (I am using Linux). mspec.exe is installed when adding the project Machine.Specifications.Runner.Console.

Finally, the script will run mspec.exe to test the MyProject.dll assembly. MyProject.dll is built through Godot Mono. Godot Mono will create the assembly file .dll based on our project name.

Yay! It works.

One drawback is that, I cannot separate the tests code fro the project. The ideal solution is to have MyProject.dll and MyProjectTest.dll. Our test code should be compiled and build the MyProjectTest.dll, and it depends on GodotSharp.dll and MyProject.dll. However, it is very troublesome, because Godot Mono is not able to add project like MonoDevelop. So, the fastest solution I have is to have the tests be compiled into one .dll.