NavisworksTransport/UnitTests/Integration/RealObjectAnimationAutomationTests.cs
tian b5cfcbf8ac feat: 集成测试新增真实物体动画验证(P0 T01-T03)
- 服务端 run-virtual-collision-test 支持 useVirtualObject=false + animatedObjectPath(ModelPath 定位,解决 DisplayName 重名)
- ResolveAnimatedObjectFromQuery 支持按 CreatePathId 的 PathId 精确匹配
- 修复 ModelItem 身份校验:ReferenceEquals 对 NW API 同一逻辑对象不同实例不可靠,改用 InstanceGuid 比较
- 新增 RealObjectAnimationAutomationTests:Ground/Hoisting/Rail 真实物体动画完整流程
  (42" Diameter=0/0/660/0,25" x 25"=0/0/769/0)
- 集成测试 9/9 通过(3 虚拟碰撞 + 1 autoPath + 2 导入 + 3 真实物体)
2026-08-04 16:52:37 +08:00

86 lines
3.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;
namespace NavisworksTransport.UnitTests.Integration
{
/// <summary>
/// 真实物体动画集成测试(覆盖计划 T01-T03高风险区真实物体姿态链
///
/// 验证点:
/// - 通过 ModelPathPathId唯一定位真实物体DisplayName 可能重名)
/// - 真实物体(非虚拟物体)沿三类路径生成动画并完整播放
/// - 真实物体模式使用 fragment 代表姿态 / 真实尺寸,而非 unit_cube 资产
///
/// 依赖模型数据Floor2_mobile_yup.nwd
/// - 0/0/660/0 = 42" Diameter 管道Rail 终点附近,同时用于 Ground/Rail
/// - 0/0/769/0 = 25" x 25" 方柱Hoisting 路径上)
/// 模型几何变化可能导致 PathId 失效,届时需重新定位。
/// </summary>
[TestClass]
[TestCategory("NavisworksIntegration")]
public class RealObjectAnimationAutomationTests
{
private const string Pipe42DiameterPathId = "0/0/660/0";
private const string Column25x25PathId = "0/0/769/0";
[TestMethod]
[Timeout(360000)]
public async Task GroundRealObject_Animation_Completes()
{
await AssertRealObjectFlowAsync("Ground", Pipe42DiameterPathId).ConfigureAwait(false);
}
[TestMethod]
[Timeout(360000)]
public async Task HoistingRealObject_Animation_Completes()
{
await AssertRealObjectFlowAsync("Hoisting", Column25x25PathId).ConfigureAwait(false);
}
[TestMethod]
[Timeout(360000)]
public async Task RailRealObject_Animation_Completes()
{
await AssertRealObjectFlowAsync("Rail", Pipe42DiameterPathId).ConfigureAwait(false);
}
private static async Task AssertRealObjectFlowAsync(string pathType, string animatedObjectPath)
{
using (var client = new NavisworksTestAutomationClient())
{
await client.EnsureServiceReadyAsync(TimeSpan.FromSeconds(90)).ConfigureAwait(false);
JObject response = await client.RunCollisionTestAsync(
pathType,
240,
useVirtualObject: false,
animatedObjectPath: animatedObjectPath).ConfigureAwait(false);
Assert.IsTrue(response.Value<bool>("ok"), "真实物体碰撞测试 HTTP 接口返回失败: " + (string)response["error"]);
JObject data = (JObject)response["data"];
Assert.IsNotNull(data, "缺少测试结果 data");
JObject animatedObject = (JObject)data["animatedObject"];
Assert.IsNotNull(animatedObject, "缺少 animatedObject");
Assert.AreEqual("RealObject", (string)animatedObject["mode"], "当前测试应使用真实物体模式");
Assert.IsFalse(string.IsNullOrWhiteSpace((string)animatedObject["displayName"]), "真实物体显示名为空");
JObject route = (JObject)data["route"];
Assert.IsNotNull(route, "缺少 route");
Assert.AreEqual(pathType, (string)route["pathType"], "返回的路径类型不匹配");
JObject animation = (JObject)data["animation"];
Assert.IsNotNull(animation, "缺少 animation");
Assert.AreEqual("Finished", (string)animation["currentState"], "动画未完成");
Assert.IsTrue((int)animation["totalFrames"] > 0, "动画总帧数应大于 0");
Assert.IsTrue(animation["detectionRecordId"] != null && (int)animation["detectionRecordId"] > 0, "检测记录 ID 无效");
Assert.IsNotNull(data["report"], "缺少碰撞报告");
}
}
}
}