ExtrabbitCode.Inventor.Testbench.UI 0.2.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package ExtrabbitCode.Inventor.Testbench.UI --version 0.2.2
                    
NuGet\Install-Package ExtrabbitCode.Inventor.Testbench.UI -Version 0.2.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ExtrabbitCode.Inventor.Testbench.UI" Version="0.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ExtrabbitCode.Inventor.Testbench.UI" Version="0.2.2" />
                    
Directory.Packages.props
<PackageReference Include="ExtrabbitCode.Inventor.Testbench.UI" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ExtrabbitCode.Inventor.Testbench.UI --version 0.2.2
                    
#r "nuget: ExtrabbitCode.Inventor.Testbench.UI, 0.2.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ExtrabbitCode.Inventor.Testbench.UI@0.2.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ExtrabbitCode.Inventor.Testbench.UI&version=0.2.2
                    
Install as a Cake Addin
#tool nuget:?package=ExtrabbitCode.Inventor.Testbench.UI&version=0.2.2
                    
Install as a Cake Tool

Inventor Testbench: writing real tests

Inventor Testbench lets an addin repository own one ordinary .NET test project. The compiled DLL is loaded by the Testbench desktop app and can contain fast logic tests, tests running inside Inventor through COM, Windows UI Automation tests, and later AI-assisted reviews.

1. Choose the packages

The packages are on nuget.org; no extra feed is needed. Every project references the core package:

<PackageReference Include="ExtrabbitCode.Inventor.Testbench" Version="0.2.1" />

Add the UI package only when the assembly contains UI tests:

<PackageReference Include="ExtrabbitCode.Inventor.Testbench.UI" Version="0.2.1" />
<PackageReference Include="Autodesk.Inventor.Sdk" Version="2.0.1" />

Add Autodesk.Inventor.Sdk directly when test source uses Inventor COM types; its build targets select the interop reference. Consumers do not reference the Testbench runner or desktop app.

Or from the command line:

dotnet add package ExtrabbitCode.Inventor.Testbench --version 0.2.1
dotnet add package ExtrabbitCode.Inventor.Testbench.UI --version 0.2.1
dotnet add package Autodesk.Inventor.Sdk --version 2.0.1

Testing against unreleased changes

Only needed when working on Testbench itself. Pack from the Testbench repository and register the output as a local feed:

dotnet pack .\ExtrabbitCode.Inventor.Testbench.Packages.slnx -c Debug
dotnet nuget add source C:\path\to\Inventor.Testbench\artifacts\packages `
  --name local-inventor-testbench

Local builds carry the version from VersionPrefix in Directory.Build.props, so reference that version to pick them up ahead of the published ones.

2. Create a test project

For a project containing UI tests, use this complete .csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="ExtrabbitCode.Inventor.Testbench" Version="0.2.1" />
    <PackageReference Include="ExtrabbitCode.Inventor.Testbench.UI" Version="0.2.1" />
    <PackageReference Include="Autodesk.Inventor.Sdk" Version="2.0.1" />
    <ProjectReference Include="..\..\src\MyInventorAddin\MyInventorAddin.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="fixtures\**\*" CopyToOutputDirectory="PreserveNewest" />
  </ItemGroup>
</Project>

CopyLocalLockFileAssemblies is important for plugin loading: it puts UI and other NuGet dependencies beside the test DLL so Inventor can resolve them.

Suggested layout:

MyAddin/
  src/MyInventorAddin/
  tests/MyInventorAddin.Testbench/
    LogicTests.cs
    InventorApiTests.cs
    AddinUiTests.cs
    fixtures/
      parts/Bracket.ipt
      assemblies/Gearbox/Gearbox.iam
      assemblies/Gearbox/Gear.ipt

3. Understand the four test kinds

Marker Runs where Use it for
[InventorFact] Local Testbench process filename rules, configuration, validation, planning and other pure .NET logic
[InventorApiFact] Inside the selected Inventor version documents, iProperties, parameters, BOM, geometry, translators and addin services using COM
[InventorUiFact] Inside Inventor with interactive desktop access ribbon buttons, dialogs, dock panes, keyboard/focus and combined UI + COM assertions
[InventorAiFact] Reserved AI category visual or exploratory review; provider execution is not wired yet, so mark these skipped today

UI tests are normally combined tests: they drive the visible addin UI and then verify the result through context.InventorApplication, documents, or generated files.

4. Fast logic test

using ExtrabbitCode.Inventor.Testbench.Abstractions;

public sealed class ExportNameTests
{
    [InventorFact("Export names contain no Windows-invalid characters",
        Tags = ["export", "naming", "fast"])]
    public void Export_name_is_safe()
    {
        string result = MyExportNames.Create("1001", "Bracket");

        TestbenchAssert.Equal("1001-Bracket.step", result);
        TestbenchAssert.False(result.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0);
    }
}

Logic tests do not need Inventor and should contain most validation, parsing, configuration, and planning behavior.

5. Inventor COM test

using ExtrabbitCode.Inventor.Testbench.Abstractions;

public sealed class PropertyTests
{
    [InventorApiFact("Tracking ID round-trips through a part",
        Tags = ["iproperty", "smoke"],
        Versions = ["2025", "2026", "2027"])]
    public void Tracking_id_round_trips(InventorTestContext context)
    {
        context.RequireInventor();
        Inventor.PartDocument part = context.CreateTempPartDocument();

        part.SetCustomProperty("TrackingId", "TB-1001");
        context.WaitForIdle();

        TestbenchAssert.Equal("TB-1001", part.GetCustomPropertyText("TrackingId"));
        context.Output.WriteLine($"Document: {part.DisplayName}");
    }
}

Versions is optional. With no value the test is eligible for 2025, 2026, and 2027. When values are declared, Testbench runs it only for those selected versions.

6. Test an existing Inventor fixture safely

Fixtures are never opened in place. OpenPartFixture, OpenAssemblyFixture, and the other typed helpers first copy the file into the test working directory.

[InventorApiFact("Bracket material remains Steel",
    Fixture = "parts/Bracket.ipt",
    Tags = ["fixture", "material"])]
public void Bracket_material_is_steel(InventorTestContext context)
{
    Inventor.PartDocument part = context.OpenPartFixture();
    TestbenchAssert.Equal("Steel", part.ActiveMaterial.DisplayName);
}

For an assembly with referenced parts, copy its entire fixture directory first:

[InventorApiFact("Gearbox opens with all references", Tags = ["assembly"])]
public void Gearbox_references_resolve(InventorTestContext context)
{
    string directory = context.CopyFixtureDirectoryToTemp("assemblies/Gearbox");
    string assemblyPath = Path.Combine(directory, "Gearbox.iam");
    Inventor.AssemblyDocument assembly = context.Adapter.OpenFixture<Inventor.AssemblyDocument>(assemblyPath);

    TestbenchAssert.True(assembly.AllReferencedDocuments.Count > 0);
}

7. UI + COM test for an addin

using ExtrabbitCode.Inventor.Testbench.Abstractions;
using ExtrabbitCode.Inventor.Testbench.UI;
using FlaUI.Core.Definitions;

public sealed class ExportDialogTests
{
    [InventorUiFact("Export button opens the dialog and exports STEP",
        Fixture = "assemblies/Gearbox/Gearbox.iam",
        Tags = ["ui", "export", "combined"])]
    public void Export_button_creates_step(InventorTestContext context)
    {
        Inventor.AssemblyDocument assembly = context.OpenAssemblyFixture();
        using InventorUiSession ui = InventorUiSession.Attach(context);

        ui.RequireByName("Export", ControlType.Button).AsButton().Invoke();
        var dialog = ui.WaitForWindow("Export");
        string expected = context.ArtifactPath("Gearbox.step");
        ui.SetTextByName("Output file", expected);
        dialog.FindFirstDescendant(cf => cf.ByName("Export"))!.AsButton().Invoke();

        TestbenchWait.UntilAsync(
            () => File.Exists(expected),
            description: "STEP export").GetAwaiter().GetResult();

        context.AddFileArtifact(expected, "step-export");
        TestbenchAssert.True(new FileInfo(expected).Length > 0);
        context.AddArtifacts(ui.CaptureDiagnostics(context.TestWorkingDirectory, "export-complete"));
    }
}

Prefer Automation ID where the addin exposes one; otherwise use accessible name plus control type. Avoid screen coordinates. Always verify functional success through COM or the output file rather than a screenshot alone.

8. Output, waits, and artifacts

Frequently used helpers:

context.Output.WriteLine("Readable trace shown in Testbench");
await TestbenchWait.UntilAsync(() => condition, TimeSpan.FromSeconds(15));
string path = context.ArtifactPath("result.pdf");
context.AddFileArtifact(path, "pdf");
context.AddArtifacts(ui.CaptureDiagnostics(context.TestWorkingDirectory, "failure-state"));

Registered files are copied into the permanent result directory before the temporary test directory is deleted. They appear in JUnit and in the Testbench details panel.

9. Build and load the DLL

dotnet build .\tests\MyInventorAddin.Testbench

In the Testbench app:

  1. Select Add test DLL in the left sidebar.
  2. Choose tests\MyInventorAddin.Testbench\bin\Debug\net8.0-windows10.0.19041.0\MyInventorAddin.Testbench.dll.
  3. Use the Logic, Inventor, UI, or AI tab to inspect one category.
  4. Select one or more installed Inventor versions for Inventor/UI tests.
  5. Run the full filtered category or use the play button on one test row.
  6. Inspect trace output, duration, per-version result badges, artifacts, JUnit, or source code.

The fixture root for an external DLL defaults to a fixtures directory beside that DLL. Copy fixtures to output as shown in the project file, or keep an output-side fixtures folder.

9b. Display an existing xunit suite

Addin repositories usually already own an xunit test project. Testbench can host those suites without a rewrite:

  • Adding a DLL that references xunit.core creates a suite in dotnet test mode. Discovery reads [Fact]/[Theory] metadata without loading the assembly, so the suite may target a newer framework (e.g. net10) than the app.
  • Running shells out to dotnet test <dll> and reads the JUnit report back. The test project must reference the JunitXml.TestLogger NuGet package.
  • A class-level [Collection] name or a trait containing "inventor" marks a test as Inventor kind for the tab filters; everything else counts as Logic.

The app can also be launched preloaded from another repository:

ExtrabbitCode.Inventor.Testbench.App.exe --add-assembly C:\repo\tests\bin\...\MyAddin.Tests.dll

--add-assembly is repeatable, persists like picker-added DLLs, and preselects the first suite. The same run works headless via the CLI:

dotnet run --project .\src\ExtrabbitCode.Inventor.Testbench.Console -- dotnet-run --assembly <dll> [--filter <fqn-substring>]

10. AI visual review with your model provider

[InventorAiFact] has its own Testbench tab. Testbench defines IAiVisualReviewer but deliberately does not own credentials or force a model vendor. Implement the interface in the test project using your OpenAI, Azure, or local-model client:

[InventorAiFact("No controls overlap at 150% DPI", Tags = ["ai", "visual"])]
public async Task Dialog_has_no_visual_defects(InventorTestContext context)
{
    using InventorUiSession ui = InventorUiSession.Attach(context);
    string image = ui.CaptureDiagnostics(context.TestWorkingDirectory, "dialog")
        .First(artifact => artifact.Kind == "ui-screenshot").Path;

    IAiVisualReviewer reviewer = new CompanyVisualReviewer(
        Environment.GetEnvironmentVariable("AI_API_KEY")!);
    await context.ReviewImageAsync(
        reviewer,
        image,
        "Approve only if labels are readable and no controls overlap or clip.");
}

The helper persists the structured result as an ai-review JSON artifact, writes findings to trace, and fails when Approved is false. Pass requireApproval: false while introducing advisory reviews. The concrete CompanyVisualReviewer is application-specific because authentication, data-retention policy, model choice, and endpoint ownership belong to the consuming organization.

Practical test pyramid

  • Put parsing, naming, configuration, and validation into many [InventorFact] tests.
  • Use [InventorApiFact] for the smaller set that proves Inventor document behavior.
  • Use [InventorUiFact] only for interaction surfaces that COM cannot exercise.
  • Use [InventorAiFact] for visual/exploratory residue, backed by deterministic evidence.

This keeps the suite fast and stable while still testing what users actually see.

Product Compatible and additional computed target framework versions.
.NET net8.0-windows10.0.19041 is compatible.  net9.0-windows was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
0.2.3 150 7/26/2026
0.2.2 113 7/25/2026
0.2.1 110 7/19/2026
0.2.0 101 7/19/2026