test: per-test очистка документов через IntegrationTestBase (CloseAllAsync)

Базовый класс IntegrationTestBase (IAsyncLifetime) закрывает все открытые
документы КОМПАС после КАЖДОГО теста (DocumentService.CloseAllAsync) — чтобы не
копились вкладки-пустышки и упавший Assert не оставлял открытый документ. Все
интеграционные тест-классы переведены на него (: base(fx)); индивидуальные
finally CloseAsync сохранены как первичная очистка.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 13:38:48 +03:00
parent 5e6d3ec8ae
commit 8afad88241
17 changed files with 71 additions and 30 deletions
@@ -8,14 +8,14 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: вставка компонента в сборку (API7 IParts7.AddFromFile + Placement).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class AssemblyTests
public sealed class AssemblyTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly AssemblyService _assembly;
private readonly QueryService _query;
public AssemblyTests(KompasFixture fx)
public AssemblyTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -3,11 +3,11 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: подключение к КОМПАС. Требует установленный КОМПАС-3D.</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class ConnectionTests
public sealed class ConnectionTests : IntegrationTestBase
{
private readonly KompasFixture _fx;
public ConnectionTests(KompasFixture fx) => _fx = fx;
public ConnectionTests(KompasFixture fx) : base(fx) => _fx = fx;
[Fact]
public void Connects_to_kompas()
@@ -8,14 +8,14 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: импорт/экспорт STEP и обход компонентов сборки.</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class ConversionTests
public sealed class ConversionTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly ConversionService _conv;
private readonly QueryService _query;
public ConversionTests(KompasFixture fx)
public ConversionTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -5,11 +5,11 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: жизненный цикл документов.</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class DocumentTests
public sealed class DocumentTests : IntegrationTestBase
{
private readonly DocumentService _docs;
public DocumentTests(KompasFixture fx)
public DocumentTests(KompasFixture fx) : base(fx)
=> _docs = new DocumentService(fx.Session, fx.Dispatcher);
[Fact]
@@ -8,14 +8,14 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: прямое редактирование — перемещение грани (FaceMover).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class FaceEditTests
public sealed class FaceEditTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly FaceEditService _faceEdit;
private readonly QueryService _query;
public FaceEditTests(KompasFixture fx)
public FaceEditTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -7,13 +7,13 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: формообразующие операции пакетов B и C (массивы, зеркало).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class FeatureOpsTests
public sealed class FeatureOpsTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly QueryService _query;
public FeatureOpsTests(KompasFixture fx)
public FeatureOpsTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -7,14 +7,14 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: операция «Отверстие» (API7 IHoles3D/IHole3D).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class HoleTests
public sealed class HoleTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly HoleService _holes;
private readonly QueryService _query;
public HoleTests(KompasFixture fx)
public HoleTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -7,13 +7,13 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: структурное «зрение» — дерево, топология, drill-down, измерения.</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class InspectionTests
public sealed class InspectionTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly ModelInspectionService _inspect;
public InspectionTests(KompasFixture fx)
public InspectionTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -0,0 +1,21 @@
using Kompas.Mcp.Core.Documents;
namespace Kompas.Mcp.Tests.Integration;
/// <summary>
/// Базовый класс интеграционных тестов: после КАЖДОГО теста закрывает все открытые документы
/// КОМПАС без сохранения, чтобы не копились вкладки-пустышки (и чтобы упавший Assert не оставлял
/// открытый документ). xUnit создаёт новый экземпляр тест-класса на каждый тест-метод, поэтому
/// <see cref="DisposeAsync"/> вызывается per-test — это и есть точка очистки.
/// </summary>
public abstract class IntegrationTestBase : IAsyncLifetime
{
private readonly DocumentService _cleanupDocs;
protected IntegrationTestBase(KompasFixture fx)
=> _cleanupDocs = new DocumentService(fx.Session, fx.Dispatcher);
public Task InitializeAsync() => Task.CompletedTask;
public Task DisposeAsync() => _cleanupDocs.CloseAllAsync();
}
@@ -8,14 +8,14 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: построение 3D (эскиз → выдавливание) и снимок.</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class ModelingTests
public sealed class ModelingTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly SnapshotService _snap;
private readonly QueryService _query;
public ModelingTests(KompasFixture fx)
public ModelingTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -7,13 +7,13 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: массово-центровочные характеристики (get_part_info).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class QueryTests
public sealed class QueryTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly QueryService _query;
public QueryTests(KompasFixture fx)
public QueryTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -7,13 +7,13 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: новые примитивы эскиза (профиль → выдавливание → объём).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class SketchPrimitivesTests
public sealed class SketchPrimitivesTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly QueryService _query;
public SketchPrimitivesTests(KompasFixture fx)
public SketchPrimitivesTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -6,12 +6,12 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: снимок модели в растр («зрение агента»).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class SnapshotTests
public sealed class SnapshotTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly SnapshotService _snap;
public SnapshotTests(KompasFixture fx)
public SnapshotTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_snap = new SnapshotService(fx.Session, fx.Dispatcher);
@@ -9,7 +9,7 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: рассечение тела, перемещение тела, объединение (cut→spread→union).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class SolidEditTests
public sealed class SolidEditTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
@@ -18,7 +18,7 @@ public sealed class SolidEditTests
private readonly QueryService _query;
private readonly ValidationService _validation;
public SolidEditTests(KompasFixture fx)
public SolidEditTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -7,13 +7,13 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: валидация построения (ошибки/перестроение операций).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class ValidationTests
public sealed class ValidationTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly ValidationService _validation;
public ValidationTests(KompasFixture fx)
public ValidationTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
@@ -7,14 +7,14 @@ namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: переменные модели (параметрика, API5 ksVariable).</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class VariableTests
public sealed class VariableTests : IntegrationTestBase
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly VariableService _vars;
private readonly ModelInspectionService _inspect;
public VariableTests(KompasFixture fx)
public VariableTests(KompasFixture fx) : base(fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);