Write unit tests for your Revit add-ins using the TUnit testing framework with source-generated tests, parallel execution, and Microsoft.Testing.Platform support.
You can install this library as a NuGet package.
The packages are compiled for specific versions of Revit. To support different versions of libraries in one project, use the RevitVersion property:
<PackageReference Include="Nice3point.TUnit.Revit" Version="$(RevitVersion).*"/>Start by creating a new class inheriting from RevitApiTest:
public class MyTestClass : RevitApiTest
{
}Add a method with [Test] and [TestExecutor<RevitThreadExecutor>] attributes:
public class MyTestClass : RevitApiTest
{
[Test]
[TestExecutor<RevitThreadExecutor>]
public async Task MyTest()
{
}
}This is your runnable test. The [TestExecutor<RevitThreadExecutor>] attribute ensures the test executes within Revit's single-threaded API context.
TUnit is built on top of the Microsoft.Testing.Platform. Combined with source-generated tests, running your tests is available in multiple ways.
For simple project execution, dotnet run is the preferred method, allowing easier command line flag passing.
cd 'C:/Your/Test/Directory'
dotnet run -c "Release.R26"dotnet test requires the configuration to target the desired Revit version.
cd 'C:/Your/Test/Directory'
dotnet test -c "Release.R26"Important
You must have a licensed copy of Autodesk Revit installed on your machine to run tests, with a version that matches the selected Solution configuration.
The Enable Testing Platform support option must be selected in Settings > Build, Execution, Deployment > Unit Testing > Testing Platform.
Test Revit application-level functionality:
public sealed class RevitApplicationTests : RevitApiTest
{
[Test]
[TestExecutor<RevitThreadExecutor>]
public async Task Cities_Startup_IsNotEmpty()
{
var cities = Application.Cities.Cast<City>();
await Assert.That(cities).IsNotEmpty();
}
[Test]
[TestExecutor<RevitThreadExecutor>]
public async Task Create_XYZ_ValidDistance()
{
var point = Application.Create.NewXYZ(3, 4, 5);
await Assert.That(point.DistanceTo(XYZ.Zero)).IsEqualTo(7).Within(0.1);
}
}Test document-specific operations with setup and cleanup:
public sealed class RevitDocumentTests : RevitApiTest
{
private static Document _documentFile = null!;
[Before(Class)]
[HookExecutor<RevitThreadExecutor>]
public static void Setup()
{
_documentFile = Application.OpenDocumentFile($@"C:\Program Files\Autodesk\Revit {Application.VersionNumber}\Samples\rac_basic_sample_family.rfa");
}
[After(Class)]
[HookExecutor<RevitThreadExecutor>]
public static void Cleanup()
{
_documentFile.Close(false);
}
[Test]
[TestExecutor<RevitThreadExecutor>]
public async Task FilteredElementCollector_ElementTypes_ValidAssignable()
{
var elements = new FilteredElementCollector(_documentFile)
.WhereElementIsElementType()
.ToElements();
using (Assert.Multiple())
{
await Assert.That(elements).IsNotEmpty();
await Assert.That(elements).All().Satisfy(element => element.IsAssignableTo<ElementType>());
}
}
[Test]
[TestExecutor<RevitThreadExecutor>]
public async Task Delete_Dimensions_ElementsWithDependenciesDeleted()
{
var elementIds = new FilteredElementCollector(_documentFile)
.WhereElementIsNotElementType()
.OfCategory(BuiltInCategory.OST_Dimensions)
.OfClass(typeof(RadialDimension))
.ToElementIds();
using var transaction = new Transaction(_documentFile);
transaction.Start("Delete dimensions");
var deletedElements = _documentFile.Delete(elementIds);
transaction.Commit();
await Assert.That(deletedElements.Count).IsGreaterThanOrEqualTo(elementIds.Count);
}
}Note
The examples demonstrate basic testing functionality. This library only adds support for working within the Revit API context. For comprehensive documentation on assertions, attributes, test configuration, and advanced features, please refer to the official TUnit documentation.
