Rhino.Testing
8.0.23-beta
dotnet add package Rhino.Testing --version 8.0.23-beta
NuGet\Install-Package Rhino.Testing -Version 8.0.23-beta
<PackageReference Include="Rhino.Testing" Version="8.0.23-beta" />
paket add Rhino.Testing --version 8.0.23-beta
#r "nuget: Rhino.Testing, 8.0.23-beta"
// Install Rhino.Testing as a Cake Addin #addin nuget:?package=Rhino.Testing&version=8.0.23-beta&prerelease // Install Rhino.Testing as a Cake Tool #tool nuget:?package=Rhino.Testing&version=8.0.23-beta&prerelease
Rhino.Testing
NUnit dotnet unit testing for Rhino3D
Setting Up Your Project
Package References
Add these package references to your project (.csproj). These references ensure your tests are discoverable by the test runner:
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="Rhino.Testing" Version="8.0.*-beta" />
</ItemGroup>
Rhino.Testing Configuration
Rhino.Testing will use Rhino.Testing.Configs.xml
file to read RhinoSystemDirectory
and setup necessary assembly resolvers for the target Rhino.
<?xml version="1.0" encoding="utf-8"?>
<Settings>
<RhinoSystemDirectory>C:\Program Files\Rhino 8\System</RhinoSystemDirectory>
</Settings>
When initializing Rhino, an empty headless document is created. You can disable this behaviour:
<CreateRhinoDoc>false</CreateRhinoDoc>
The default document will be assigned an active view as well. You can disable this behaviour:
<CreateRhinoView>false</CreateRhinoView>
Specify Eto or RDK to be loaded (if LoadGrasshopper
is specified, Eto and RDK will be automatically loaded):
<LoadEto>true</LoadEto>
<LoadRDK>true</LoadRDK>
If you want Rhino.Testing to load Eto you must not include Eto in your build directory or both assemblies will try to load, and it will fail. Below the Eto.Forms nuget is set to not copy to the build direcotry
<PackageReference Include="Eto" Version="2.8.4" Private="False" PrivateAssets="all" />
Specify Legacy IronPython to be loaded:
<LoadLegacyIronPython>true</LoadLegacyIronPython>
Specify list of plugins to be loaded (These plugins are always loaded before Grasshopper)
<LoadPlugins>
<Plugin Location="Plug-ins\IronPython\RhinoDLR_Python.rhp" />
<Plugin Location="MyPlugins\MyRhinoPlugin.rhp" />
</LoadPlugins>
Specify Grasshopper to be loaded:
<LoadGrasshopper>true</LoadGrasshopper>
Make sure this file is copied onto the build folder (where Rhino.Testing.dll
exists):
<ItemGroup>
<None Update="Rhino.Testing.Configs.xml" CopyToOutputDirectory="always" />
</ItemGroup>
Rhino.Testing.Configs.xml
can also contains any other configuration you want for your project. You can deserialize the xml file into your own settings:
[Serializable]
[XmlRoot("Settings")]
public sealed class MyTestSettings
{
[XmlElement]
public string MySetting { get; set; }
}
// use the default settings file (or your own xml file)
string settingsFile = Rhino.Testing.Configs.SettingsFile;
// create an xml serializer for your settings type
XmlSerializer serializer = new XmlSerializer(typeof(MyTestSettings));
// deserialize your settings
var settings = Rhino.Testing.Configs.Deserialize<MyTestSettings>(serializer, settingsFile);
Test Setup Fixture
There are two ways to ensure Rhino is loaded and ready before your tests are executed:
- Applying
Rhino.Testing.Fixtures.RhinoTestFixtureAttribute
to your test fixtures - Deriving your test fixtures from
Rhino.Testing.Fixtures.RhinoSetupFixture
Using RhinoTestFixtureAttribute
is usually better since it allows using RhinoCommon data types during test discovery. For example, without using the attribute, the test below fails during discovery since test-host does not have access to RhinoCommon. Using the RhinoTestFixtureAttribute
however makes sure that Rhino is loaded during test discovery in the host:
[RhinoTestFixture] // remove this attribute and test fails to load
public class Point3dTest
{
[Test]
[TestCaseSource(nameof(PointList))]
public void Test(Point3d point)
{
Assert.That(point.X, Is.GreaterThan(0));
Assert.That(point.Y, Is.GreaterThan(0));
Assert.That(point.Z, Is.GreaterThan(0));
}
public static IEnumerable PointList()
{
yield return new TestCaseData(new Point3d(1, 2, 3));
yield return new TestCaseData(new Point3d(4, 5, 6));
yield return new TestCaseData(new Point3d(7, 8, 9));
}
}
Is also means you do not have to add an implementation of RhinoSetupFixture
in your tests to initialize Rhino.
Using Setup Attribute
Add RhinoTestFixtureAttribute
to any class to ensure Rhino is initialized for your test:
[RhinoTestFixture]
public sealed class PrimitivesFixture
{
[Test]
public void YourRhinoTest()
{
// you rhino test
}
}
Note that your test case does not need to be derived from any specific base class. However deriving from Rhino.Testing.Fixtures.RhinoTestFixture
gives you access to extra functionality discussed below.
Using Setup Fixture
Implement the Rhino.Testing.Fixtures.RhinoSetupFixture
abstract class in your test library to setup and teardown your testing fixture. This ensures Rhino is setup before testing starts and torn down after tests are done:
[SetUpFixture]
public sealed class SetupFixture : Rhino.Testing.Fixtures.RhinoSetupFixture
{
public override void OneTimeSetup()
{
base.OneTimeSetup();
// your custom setup
}
public override void OneTimeTearDown()
{
base.OneTimeTearDown();
// you custom teardown
}
}
Mixing Setup Fixture and Attribute
It is okay to mix using RhinoSetupFixture
and RhinoTestFixtureAttribute
in your test projects:
- Ensure
RhinoTestFixtureAttribute
is added to all test fixtures that use RhinoCommon data types to ensure they are correctly processed during test discovery - Derive from
RhinoSetupFixture
to add custom initialization logic that is necessary before tests are actually executed (this is after the test discovery step). For example you can make sure a few needed Rhino or Grasshopper plugins are loaded before testing starts. Loading of these plugins is most probably not necessary during test discovery.
Loading GHAs for Testing
If your tests required a Grasshopper definition to be loaded, you can use RhinoSetupFixture.LoadGHA(IEnumerable<string> ghaPaths)
method:
[SetUpFixture]
public sealed class SetupFixture : Rhino.Testing.Fixtures.RhinoSetupFixture
{
public override void OneTimeSetup()
{
base.OneTimeSetup();
LoadGHA(new string[] {
@"/path/to/gh1plugins/FirstTestPlugin.gha",
@"/path/to/gh1plugins/SecondTestPlugin.gha",
});
}
}
These GH plugins will be loaded during startup.
Test Fixtures
Implement the Rhino.Testing.Fixtures.RhinoTestFixture
abstract class in your test library, add methods for each of your test and make sure to add the [Test]
attribute to these methods:
[TestFixture]
public sealed class PrimitivesFixture : Rhino.Testing.Fixtures.RhinoTestFixture
{
[Test]
public void YourRhinoTest()
{
// you rhino test
}
}
Testing Grasshopper Files
You can run Grasshopper definitions as tests. If definition contains a Context Bake component that is named result
, the data structure in that definition is checked for GH_Boolean values and the result is returned.
Notice the Context Bake component at the right side of this definition:
This is how the fixture would run the definition:
[TestFixture]
public sealed class PrimitivesFixture : Rhino.Testing.Fixtures.RhinoTestFixture
{
[Test]
public void TestCircle()
{
const string ghFilePath = @"Files\circle.gh";
RhinoTestFixture.TestGrasshopper(ghFilePath, out bool result, out GHReport report);
// check if result is true
Assert.IsTrue(result);
// and report has no errors
Assert.IsFalse(report.HasErrors);
}
}
The GHReport
data structure contains any component messages after definition is solved. You can filter the level of messages by passing GHMessageLevel reportLevel
argument:
[TestFixture]
public sealed class PrimitivesFixture : Rhino.Testing.Fixtures.RhinoTestFixture
{
[Test]
public void TestCircle()
{
const string ghFilePath = @"Files\circle.gh";
RhinoTestFixture.TestGrasshopper(ghFilePath,
out bool result,
out GHReport report,
GHMessageLevel.Warning);
}
}
You can also use the simpler RhinoTestFixture.RunGrasshopper
method that does not expect a Context Bake component named result
. This way you can implement your own testing logic. The function still returns a GHReport report
.
[TestFixture]
public sealed class PrimitivesFixture : Rhino.Testing.Fixtures.RhinoTestFixture
{
[Test]
public void TestCircle()
{
const string ghFilePath = @"Files\circle.gh";
RhinoTestFixture.RunGrasshopper(ghFilePath,
out GHReport report,
GHMessageLevel.Warning);
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net7.0-windows7.0 is compatible. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Framework | net48 is compatible. net481 was computed. |
-
.NETFramework 4.8
- NUnit (>= 3.14.0)
- NUnit3TestAdapter (>= 4.6.0)
-
net7.0
- NUnit (>= 3.14.0)
- NUnit3TestAdapter (>= 4.6.0)
-
net7.0-windows7.0
- NUnit (>= 3.14.0)
- NUnit3TestAdapter (>= 4.6.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
8.0.23-beta | 278 | 9/10/2024 |
8.0.17-beta | 178 | 6/26/2024 |
8.0.16-beta | 808 | 5/6/2024 |
8.0.15-beta | 81 | 5/5/2024 |
8.0.14-beta | 83 | 4/10/2024 |
8.0.13-beta | 77 | 4/2/2024 |
8.0.12-beta | 73 | 3/27/2024 |
8.0.11-beta | 71 | 3/27/2024 |
8.0.10-beta | 301 | 3/26/2024 |
8.0.9-beta | 216 | 2/28/2024 |
8.0.8-beta | 62 | 2/28/2024 |
8.0.7-beta | 66 | 2/28/2024 |
8.0.6-beta | 66 | 2/20/2024 |
8.0.5-beta | 86 | 2/20/2024 |
8.0.4-beta | 77 | 2/14/2024 |
8.0.3-beta | 66 | 2/12/2024 |
8.0.2-beta | 61 | 2/12/2024 |
8.0.1-beta | 63 | 2/12/2024 |
8.0.0-beta | 66 | 2/12/2024 |