From ac1a9312374d842078902649aceec898bc9fac4a Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Mon, 29 Sep 2025 10:24:18 +0200 Subject: [PATCH 01/18] Removed build_machine parameter --- tests/system/extensions/conftest.py | 1 - tests/system/filter_solutions/conftest.py | 1 - tests/system/general/conftest.py | 1 - tests/system/general/test_98_Icepak.py | 4 +++- tests/system/solvers/conftest.py | 1 - tests/system/visualization/conftest.py | 1 - 6 files changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py index 168e5e68446..fe3d8ac0b74 100644 --- a/tests/system/extensions/conftest.py +++ b/tests/system/extensions/conftest.py @@ -84,7 +84,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "build_machine": True, "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py index 6e2a2e1549d..1a764834cbf 100644 --- a/tests/system/filter_solutions/conftest.py +++ b/tests/system/filter_solutions/conftest.py @@ -80,7 +80,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "build_machine": True, "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index 3eef1b28461..fcc03915ec8 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -87,7 +87,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "build_machine": True, "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, diff --git a/tests/system/general/test_98_Icepak.py b/tests/system/general/test_98_Icepak.py index 6a57af327d4..72d15d22a38 100644 --- a/tests/system/general/test_98_Icepak.py +++ b/tests/system/general/test_98_Icepak.py @@ -68,6 +68,8 @@ solution_freq = "2.5GHz" resolution = 2 +on_ci = os.getenv("ON_CI", "false").lower() == "true" + @pytest.fixture(autouse=True) def ipk(add_app, request) -> Icepak: @@ -742,7 +744,7 @@ def test036__check_bounding_box(self, ipk): real_bound = obj_2_bbox assert abs(sum([i - j for i, j in zip(exp_bounding, real_bound)])) < tol - @pytest.mark.skipif(config["build_machine"], reason="Needs Workbench to run.") + @pytest.mark.skipif(on_ci, reason="Needs Workbench to run.") @pytest.mark.parametrize("ipk", [cold_plate], indirect=True) def test037__export_fluent_mesh(self, ipk): assert ipk.get_liquid_objects() == ["Liquid"] diff --git a/tests/system/solvers/conftest.py b/tests/system/solvers/conftest.py index f04e8ecda39..4bc66672cf1 100644 --- a/tests/system/solvers/conftest.py +++ b/tests/system/solvers/conftest.py @@ -86,7 +86,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "build_machine": True, "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py index cd846b04e46..047c660a0dd 100644 --- a/tests/system/visualization/conftest.py +++ b/tests/system/visualization/conftest.py @@ -87,7 +87,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "build_machine": True, "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, From c473b0aea04c776e5f291651b0ff75e7fc9f3965 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Mon, 29 Sep 2025 10:25:56 +0200 Subject: [PATCH 02/18] Removed skip_space_claim parameter --- tests/system/extensions/conftest.py | 1 - tests/system/filter_solutions/conftest.py | 1 - tests/system/general/conftest.py | 1 - tests/system/solvers/conftest.py | 1 - tests/system/visualization/conftest.py | 1 - 5 files changed, 5 deletions(-) diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py index fe3d8ac0b74..1c8ff65c2be 100644 --- a/tests/system/extensions/conftest.py +++ b/tests/system/extensions/conftest.py @@ -84,7 +84,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, "skip_debug": False, diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py index 1a764834cbf..e1581481fa6 100644 --- a/tests/system/filter_solutions/conftest.py +++ b/tests/system/filter_solutions/conftest.py @@ -80,7 +80,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, "skip_debug": False, diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index fcc03915ec8..1c71ce26f62 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -87,7 +87,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, "skip_debug": False, diff --git a/tests/system/solvers/conftest.py b/tests/system/solvers/conftest.py index 4bc66672cf1..ef662c8c82a 100644 --- a/tests/system/solvers/conftest.py +++ b/tests/system/solvers/conftest.py @@ -86,7 +86,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, "skip_debug": False, diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py index 047c660a0dd..1a789d88142 100644 --- a/tests/system/visualization/conftest.py +++ b/tests/system/visualization/conftest.py @@ -87,7 +87,6 @@ "NonGraphical": True, "NewThread": True, "skip_desktop_test": False, - "skip_space_claim": False, "skip_circuits": False, "skip_edb": False, "skip_debug": False, From a119debc0715c394e9e651c9ad895418075920c7 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Mon, 29 Sep 2025 10:27:13 +0200 Subject: [PATCH 03/18] Removed skip_edb parameter --- tests/system/extensions/conftest.py | 1 - tests/system/filter_solutions/conftest.py | 1 - tests/system/general/conftest.py | 1 - tests/system/solvers/conftest.py | 1 - tests/system/visualization/conftest.py | 1 - 5 files changed, 5 deletions(-) diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py index 1c8ff65c2be..f0d971eb053 100644 --- a/tests/system/extensions/conftest.py +++ b/tests/system/extensions/conftest.py @@ -85,7 +85,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_edb": False, "skip_debug": False, "skip_modelithics": True, "local": False, diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py index e1581481fa6..a760f53123b 100644 --- a/tests/system/filter_solutions/conftest.py +++ b/tests/system/filter_solutions/conftest.py @@ -81,7 +81,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_edb": False, "skip_debug": False, "skip_modelithics": True, "local": False, diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index 1c71ce26f62..ce048732f55 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -88,7 +88,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_edb": False, "skip_debug": False, "local": False, "use_grpc": True, diff --git a/tests/system/solvers/conftest.py b/tests/system/solvers/conftest.py index ef662c8c82a..e3b197d5519 100644 --- a/tests/system/solvers/conftest.py +++ b/tests/system/solvers/conftest.py @@ -87,7 +87,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_edb": False, "skip_debug": False, "skip_modelithics": True, "local": False, diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py index 1a789d88142..96833d6292a 100644 --- a/tests/system/visualization/conftest.py +++ b/tests/system/visualization/conftest.py @@ -88,7 +88,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_edb": False, "skip_debug": False, "skip_modelithics": True, "local": False, From fb7bb2c69fc9e676796d7eea90526b001b7a1277 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Mon, 29 Sep 2025 10:28:28 +0200 Subject: [PATCH 04/18] Removed skip_debug parameter --- tests/system/extensions/conftest.py | 1 - tests/system/filter_solutions/conftest.py | 1 - tests/system/general/conftest.py | 1 - tests/system/solvers/conftest.py | 1 - tests/system/visualization/conftest.py | 1 - 5 files changed, 5 deletions(-) diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py index f0d971eb053..034534ac58e 100644 --- a/tests/system/extensions/conftest.py +++ b/tests/system/extensions/conftest.py @@ -85,7 +85,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_debug": False, "skip_modelithics": True, "local": False, "use_grpc": True, diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py index a760f53123b..c352efbd7c9 100644 --- a/tests/system/filter_solutions/conftest.py +++ b/tests/system/filter_solutions/conftest.py @@ -81,7 +81,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_debug": False, "skip_modelithics": True, "local": False, "use_grpc": True, diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index ce048732f55..de1925886d1 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -88,7 +88,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_debug": False, "local": False, "use_grpc": True, "disable_sat_bounding_box": True, diff --git a/tests/system/solvers/conftest.py b/tests/system/solvers/conftest.py index e3b197d5519..51b812db699 100644 --- a/tests/system/solvers/conftest.py +++ b/tests/system/solvers/conftest.py @@ -87,7 +87,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_debug": False, "skip_modelithics": True, "local": False, "use_grpc": True, diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py index 96833d6292a..b105a3a741f 100644 --- a/tests/system/visualization/conftest.py +++ b/tests/system/visualization/conftest.py @@ -88,7 +88,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "skip_debug": False, "skip_modelithics": True, "local": False, "use_grpc": True, From 4c4fb76f2d6897f1d5305ac4cd20eb83a9525c12 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Mon, 29 Sep 2025 10:29:20 +0200 Subject: [PATCH 05/18] Removed local parameter --- tests/system/extensions/conftest.py | 1 - tests/system/filter_solutions/conftest.py | 1 - tests/system/general/conftest.py | 1 - tests/system/solvers/conftest.py | 1 - tests/system/visualization/conftest.py | 1 - 5 files changed, 5 deletions(-) diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py index 034534ac58e..6d85ded23fd 100644 --- a/tests/system/extensions/conftest.py +++ b/tests/system/extensions/conftest.py @@ -86,7 +86,6 @@ "skip_desktop_test": False, "skip_circuits": False, "skip_modelithics": True, - "local": False, "use_grpc": True, "disable_sat_bounding_box": True, "close_desktop": True, diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py index c352efbd7c9..ac6499e66b2 100644 --- a/tests/system/filter_solutions/conftest.py +++ b/tests/system/filter_solutions/conftest.py @@ -82,7 +82,6 @@ "skip_desktop_test": False, "skip_circuits": False, "skip_modelithics": True, - "local": False, "use_grpc": True, "disable_sat_bounding_box": True, "local_example_folder": None, diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index de1925886d1..0f6c61cd7ab 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -88,7 +88,6 @@ "NewThread": True, "skip_desktop_test": False, "skip_circuits": False, - "local": False, "use_grpc": True, "disable_sat_bounding_box": True, "use_local_example_data": False, diff --git a/tests/system/solvers/conftest.py b/tests/system/solvers/conftest.py index 51b812db699..aee5bf56123 100644 --- a/tests/system/solvers/conftest.py +++ b/tests/system/solvers/conftest.py @@ -88,7 +88,6 @@ "skip_desktop_test": False, "skip_circuits": False, "skip_modelithics": True, - "local": False, "use_grpc": True, "disable_sat_bounding_box": True, "close_desktop": True, diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py index b105a3a741f..35a5423b089 100644 --- a/tests/system/visualization/conftest.py +++ b/tests/system/visualization/conftest.py @@ -89,7 +89,6 @@ "skip_desktop_test": False, "skip_circuits": False, "skip_modelithics": True, - "local": False, "use_grpc": True, "disable_sat_bounding_box": True, "close_desktop": True, From 2d608a00f4ef60efaf7af04cf561d7cd0c80414d Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Mon, 29 Sep 2025 11:13:26 +0200 Subject: [PATCH 06/18] Removed skip_desktop_test parameter --- tests/system/emit/conftest.py | 1 - tests/system/extensions/conftest.py | 2 -- tests/system/filter_solutions/conftest.py | 2 -- tests/system/general/conftest.py | 2 -- tests/system/general/test_launch_desktop.py | 1 - tests/system/solvers/conftest.py | 2 -- tests/system/visualization/conftest.py | 2 -- 7 files changed, 12 deletions(-) diff --git a/tests/system/emit/conftest.py b/tests/system/emit/conftest.py index efb619e1756..ebf9aaacda0 100644 --- a/tests/system/emit/conftest.py +++ b/tests/system/emit/conftest.py @@ -37,7 +37,6 @@ "desktopVersion": "2022.2", "NonGraphical": false, "NewThread": false, - "skip_desktop_test": false } """ diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py index 6d85ded23fd..e7f3dfb34be 100644 --- a/tests/system/extensions/conftest.py +++ b/tests/system/extensions/conftest.py @@ -37,7 +37,6 @@ "desktopVersion": "2022.2", "NonGraphical": false, "NewThread": false, - "skip_desktop_test": false } """ @@ -83,7 +82,6 @@ "desktopVersion": default_version, "NonGraphical": True, "NewThread": True, - "skip_desktop_test": False, "skip_circuits": False, "skip_modelithics": True, "use_grpc": True, diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py index ac6499e66b2..87bb7e0cc31 100644 --- a/tests/system/filter_solutions/conftest.py +++ b/tests/system/filter_solutions/conftest.py @@ -37,7 +37,6 @@ "desktopVersion": "2022.2", "NonGraphical": false, "NewThread": false, - "skip_desktop_test": false } """ @@ -79,7 +78,6 @@ "desktopVersion": default_version, "NonGraphical": True, "NewThread": True, - "skip_desktop_test": False, "skip_circuits": False, "skip_modelithics": True, "use_grpc": True, diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index 0f6c61cd7ab..30ce4ac4ed8 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -37,7 +37,6 @@ "desktopVersion": "2022.2", "NonGraphical": false, "NewThread": false, - "skip_desktop_test": false } """ @@ -86,7 +85,6 @@ "desktopVersion": default_version, "NonGraphical": True, "NewThread": True, - "skip_desktop_test": False, "skip_circuits": False, "use_grpc": True, "disable_sat_bounding_box": True, diff --git a/tests/system/general/test_launch_desktop.py b/tests/system/general/test_launch_desktop.py index aada6fe505c..f7c2a2d4d50 100644 --- a/tests/system/general/test_launch_desktop.py +++ b/tests/system/general/test_launch_desktop.py @@ -48,7 +48,6 @@ settings.wait_for_license = True -@pytest.mark.skipif(config["skip_desktop_test"], reason="Desktop tests are not selected by default.") class TestClass: def test_run_desktop_mechanical(self): aedtapp = Mechanical(solution_type=SolutionsMechanical.SteadyStateThermal) diff --git a/tests/system/solvers/conftest.py b/tests/system/solvers/conftest.py index aee5bf56123..4d0625659be 100644 --- a/tests/system/solvers/conftest.py +++ b/tests/system/solvers/conftest.py @@ -37,7 +37,6 @@ "desktopVersion": "2022.2", "NonGraphical": false, "NewThread": false, - "skip_desktop_test": false } """ @@ -85,7 +84,6 @@ "desktopVersion": default_version, "NonGraphical": True, "NewThread": True, - "skip_desktop_test": False, "skip_circuits": False, "skip_modelithics": True, "use_grpc": True, diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py index 35a5423b089..bb6cd5c344f 100644 --- a/tests/system/visualization/conftest.py +++ b/tests/system/visualization/conftest.py @@ -37,7 +37,6 @@ "desktopVersion": "2022.2", "NonGraphical": false, "NewThread": false, - "skip_desktop_test": false } """ @@ -86,7 +85,6 @@ "desktopVersion": default_version, "NonGraphical": True, "NewThread": True, - "skip_desktop_test": False, "skip_circuits": False, "skip_modelithics": True, "use_grpc": True, From a4ff090ebb10258ac0a16dbc018a086d15d61ee7 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Thu, 2 Oct 2025 12:56:21 +0200 Subject: [PATCH 07/18] Refactored conftest to be unified --- .gitignore | 5 +- tests/conftest.py | 154 ++++++++++++- tests/system/conftest.py | 134 +++++++++++ tests/system/emit/conftest.py | 125 +---------- tests/system/emit/test_emit.py | 2 +- tests/system/extensions/conftest.py | 173 +-------------- tests/system/filter_solutions/conftest.py | 95 +------- tests/system/general/conftest.py | 166 +------------- tests/system/general/test_01_3dlayout_edb.py | 2 +- tests/system/general/test_01_Design.py | 4 +- .../general/test_01_configuration_files.py | 2 +- tests/system/general/test_02_3D_modeler.py | 2 +- tests/system/general/test_03_Materials.py | 2 +- tests/system/general/test_04_SBR.py | 2 +- tests/system/general/test_05_Mesh.py | 4 +- .../system/general/test_06_MessageManager.py | 2 +- tests/system/general/test_08_Primitives3D.py | 2 +- .../system/general/test_09_VariableManager.py | 2 +- tests/system/general/test_11_Setup.py | 2 +- tests/system/general/test_13_LoadAEDTFile.py | 2 +- tests/system/general/test_14_AedtLogger.py | 2 +- tests/system/general/test_20_HFSS.py | 4 +- tests/system/general/test_21_Circuit.py | 2 +- .../general/test_22_Circuit_DynamicLink.py | 2 +- tests/system/general/test_27_Maxwell2D.py | 2 +- tests/system/general/test_28_Maxwell3D.py | 4 +- tests/system/general/test_30_Q2D.py | 2 +- tests/system/general/test_34_TwinBuilder.py | 8 +- .../general/test_36_Q2D_PostProcessing.py | 2 +- .../general/test_41_3dlayout_modeler.py | 2 +- tests/system/general/test_43_CableModeling.py | 2 +- .../system/general/test_47_CircuitNetlist.py | 2 +- tests/system/general/test_98_Icepak.py | 2 +- tests/system/general/test_launch_desktop.py | 2 +- tests/system/solvers/conftest.py | 209 +----------------- .../solvers/sequential/test_3dlayout_dcir.py | 2 +- .../sequential/test_icepak_3d_component.py | 2 +- tests/system/solvers/test_00_analyze.py | 4 +- tests/system/solvers/test_01_pdf.py | 4 +- tests/system/visualization/conftest.py | 192 +--------------- tests/unit/conftest.py | 27 --- tests/unit/extensions/conftest.py | 95 ++++---- 42 files changed, 416 insertions(+), 1039 deletions(-) create mode 100644 tests/system/conftest.py delete mode 100644 tests/unit/conftest.py diff --git a/.gitignore b/.gitignore index a950366a84e..ba1713f0fb5 100644 --- a/.gitignore +++ b/.gitignore @@ -372,12 +372,11 @@ dist/ /htmlcov/ /coverage.xml /tests/system/general/coverage.xml -/tests/system/general/local_config.json /tests/system/solvers/coverage.xml -/tests/system/solvers/local_config.json /tests/unit/coverage.xml test-results.xml test-output.xml +*local_config.json # Scratch Jupyter Notebooks scratch_notebooks/ @@ -397,12 +396,10 @@ model.index\+ # local environment settings used by e.g. Visual Studio Code /.env -/doc/source/local_config.json /.venv* # test coverage output /.cov/ -/tests/system/visualization/local_config.json /tests/system/general/pyaedt_settings.yaml # Custom instructions for GitHub Copilot diff --git a/tests/conftest.py b/tests/conftest.py index d0ca479bb6a..1d69983d2c8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -22,12 +22,24 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import json +import os +from pathlib import Path +import random +import shutil +import string import sys +import tempfile from typing import List from unittest.mock import MagicMock import pytest +from ansys.aedt.core.aedt_logger import pyaedt_logger +from ansys.aedt.core.generic.settings import settings +from ansys.aedt.core.internal.filesystem import Scratch + +# Test category prefixes for marker assignment UNIT_TEST_PREFIX = "tests/unit" INTEGRATION_TEST_PREFIX = "tests/integration" SYSTEM_TEST_PREFIX = "tests/system" @@ -38,8 +50,107 @@ FILTER_SOLUTIONS_TEST_PREFIX = "tests/system/filter_solutions" EMIT_TEST_PREFIX = "tests/system/emit" +# Global settings configuration - applied to all tests +settings.enable_local_log_file = False +settings.enable_global_log_file = False +settings.number_of_grpc_api_retries = 6 +settings.retry_n_times_time_interval = 0.5 +settings.enable_error_handler = False +settings.enable_desktop_logs = False +settings.desktop_launch_timeout = 180 +settings.release_on_exception = False +settings.wait_for_license = True +settings.enable_pandas_output = True + +# Initialize default configuration - shared across all test types +default_version = "2025.2" +os.environ[ + "ANSYSEM_FEATURE_SS544753_ICEPAK_VIRTUALMESHREGION_PARADIGM_ENABLE" +] = "1" + +DEFAULT_CONFIG = { + "desktopVersion": default_version, + "NonGraphical": True, + "NewThread": True, + "skip_circuits": False, + "skip_modelithics": True, + "use_grpc": True, + "disable_sat_bounding_box": True, + "close_desktop": True, + "remove_lock": False, + "local_example_folder": None, + "use_local_example_data": False, +} + +# Load top-level configuration +local_path = Path(__file__).parent +local_config_file = local_path / "local_config.json" + +config = DEFAULT_CONFIG.copy() +if local_config_file.exists(): + try: + with open(local_config_file) as f: + local_config = json.load(f) + config.update(local_config) + except Exception: # pragma: no cover + pass + +# Apply global configuration moved into a function for reuse and to support updates from nested conftest files +def apply_global_configuration(cfg: dict): + """Apply global configuration settings from a configuration dictionary. + + This updates module-level variables, the shared `settings` object and environment + variables. Defaults are taken from DEFAULT_CONFIG when keys are missing. + """ + global NONGRAPHICAL, desktop_version, new_thread, close_desktop, remove_lock, logger + + NONGRAPHICAL = cfg.get("NonGraphical", DEFAULT_CONFIG.get("NonGraphical")) + settings.disable_bounding_box_sat = cfg.get( + "disable_sat_bounding_box", DEFAULT_CONFIG.get("disable_sat_bounding_box") + ) + desktop_version = cfg.get("desktopVersion", DEFAULT_CONFIG.get("desktopVersion")) + new_thread = cfg.get("NewThread", DEFAULT_CONFIG.get("NewThread")) + settings.use_grpc_api = cfg.get("use_grpc", DEFAULT_CONFIG.get("use_grpc")) + close_desktop = cfg.get("close_desktop", DEFAULT_CONFIG.get("close_desktop")) + remove_lock = cfg.get("remove_lock", DEFAULT_CONFIG.get("remove_lock")) + settings.use_local_example_data = cfg.get( + "use_local_example_data", DEFAULT_CONFIG.get("use_local_example_data") + ) + if settings.use_local_example_data: + settings.local_example_folder = cfg.get( + "local_example_folder", DEFAULT_CONFIG.get("local_example_folder") + ) + + logger = pyaedt_logger + os.environ["PYAEDT_SCRIPT_VERSION"] = cfg.get( + "desktopVersion", DEFAULT_CONFIG.get("desktopVersion") + ) + +# Call the function to apply the current config values +apply_global_configuration(config) + +# Add current path to sys.path for imports +sys.path.append(str(local_path)) + +def generate_random_string(length): + """Generate a random string of specified length.""" + characters = string.ascii_letters + string.digits + random_string = "".join(random.sample(characters, length)) + return random_string -def pytest_collection_modifyitems(config: pytest.Config, items: List[pytest.Item]): + +def generate_random_ident(): + """Generate a random identifier for test folders.""" + ident = ( + "-" + generate_random_string(6) + "-" + + generate_random_string(6) + "-" + generate_random_string(6) + ) + return ident + + +def pytest_collection_modifyitems( + config: pytest.Config, items: List[pytest.Item] +): """Hook used to apply marker on tests.""" for item in items: # Mark unit, integration and system tests @@ -64,8 +175,40 @@ def pytest_collection_modifyitems(config: pytest.Config, items: List[pytest.Item item.add_marker(pytest.mark.emit) +# ================================ +# SHARED FIXTURES +# ================================ + +@pytest.fixture(scope="session", autouse=True) +def init_scratch(): + """Initialize a global scratch directory for all tests.""" + test_folder_name = "pyaedt_test" + generate_random_ident() + test_folder = Path(tempfile.gettempdir()) / test_folder_name + try: + os.makedirs(test_folder, mode=0o777) + except FileExistsError as e: + print(f"Failed to create {test_folder}. Reason: {e}") + + yield test_folder + + try: + shutil.rmtree(test_folder, ignore_errors=True) + except Exception as e: + print(f"Failed to delete {test_folder}. Reason: {e}") + + +@pytest.fixture(scope="module", autouse=True) +def local_scratch(init_scratch): + """Provide a module-scoped scratch directory.""" + tmp_path = init_scratch + scratch = Scratch(tmp_path) + yield scratch + scratch.remove() + + @pytest.fixture def touchstone_file(tmp_path): + """Create a dummy touchstone file for testing.""" file_path = tmp_path / "dummy.s2p" file_content = """ ! Terminal data exported @@ -80,6 +223,7 @@ def touchstone_file(tmp_path): @pytest.fixture() def patch_graphics_modules(monkeypatch): + """Patch graphics modules to avoid headless env issues.""" modules = [ "matplotlib", "matplotlib.pyplot", @@ -100,8 +244,12 @@ def patch_graphics_modules(monkeypatch): # Specific action to make a mock an attribute of another mock mocks["matplotlib"].pyplot = mocks["matplotlib.pyplot"] - mocks["ansys.tools.visualization_interface"].backends = mocks["ansys.tools.visualization_interface.backends"] - mocks["ansys.tools.visualization_interface.backends"].pyvista = mocks[ + viz_interface = mocks["ansys.tools.visualization_interface"] + viz_backends = mocks[ + "ansys.tools.visualization_interface.backends" + ] + viz_interface.backends = viz_backends + viz_backends.pyvista = mocks[ "ansys.tools.visualization_interface.backends.pyvista" ] diff --git a/tests/system/conftest.py b/tests/system/conftest.py new file mode 100644 index 00000000000..37616cd8293 --- /dev/null +++ b/tests/system/conftest.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import os +import tempfile + +import pytest + +from ansys.aedt.core import Desktop +from ansys.aedt.core.edb import Edb +from ansys.aedt.core.filtersolutions import DistributedDesign +from ansys.aedt.core.filtersolutions import LumpedDesign +from ansys.aedt.core.generic.file_utils import generate_unique_name +from ansys.aedt.core.hfss import Hfss +from tests import TESTS_GENERAL_PATH +from tests.conftest import NONGRAPHICAL +from tests.conftest import config + + +@pytest.fixture(scope="module", autouse=True) +def desktop(): + d = Desktop(config["desktopVersion"], NONGRAPHICAL, config["NewThread"]) + d.odesktop.SetTempDirectory(tempfile.gettempdir()) + d.disable_autosave() + + yield d + try: + d.close_desktop() + except Exception: + return False + +@pytest.fixture(scope="module") +def add_app(local_scratch): + def _method( + project_name=None, design_name=None, solution_type=None, application=None, subfolder="", just_open=False + ): + if project_name and not just_open: + example_project = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedt") + example_folder = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedb") + if os.path.exists(example_project): + # Copy unit test project to scratch folder. Return full file path to the project without extension. + test_project = local_scratch.copyfile(example_project) + elif os.path.exists(example_project + "z"): + example_project = example_project + "z" + test_project = local_scratch.copyfile(example_project) + else: + test_project = os.path.join(local_scratch.path, project_name + ".aedt") + if os.path.exists(example_folder): + target_folder = os.path.join(local_scratch.path, project_name + ".aedb") + local_scratch.copyfolder(example_folder, target_folder) + elif project_name and just_open: + test_project = project_name + else: + test_project = None + if not application: + application = Hfss + + args = { + "project": test_project, + "design": design_name, + "version": config["desktopVersion"], + "non_graphical": NONGRAPHICAL, + "remove_lock": True, + } + if solution_type: + args["solution_type"] = solution_type + return application(**args) + + return _method + +@pytest.fixture(scope="module") +def test_project_file(local_scratch): + def _method(project_name=None, subfolder=None): + if subfolder: + project_file = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedt") + else: + project_file = os.path.join(local_scratch.path, project_name + ".aedt") + if os.path.exists(project_file): + return project_file + else: + return None + + return _method + +@pytest.fixture(scope="module") +def add_edb(local_scratch): + def _method(project_name=None, subfolder=""): + if project_name: + example_folder = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedb") + if os.path.exists(example_folder): + target_folder = os.path.join(local_scratch.path, project_name + ".aedb") + local_scratch.copyfolder(example_folder, target_folder) + else: + target_folder = os.path.join(local_scratch.path, project_name + ".aedb") + else: + target_folder = os.path.join(local_scratch.path, generate_unique_name("TestEdb") + ".aedb") + return Edb( + target_folder, + edbversion=config["desktopVersion"], + ) + + return _method + +@pytest.fixture(scope="function") +def lumped_design(): + """Fixture for creating a LumpedDesign object.""" + return LumpedDesign(config["desktopVersion"]) + + +@pytest.fixture(scope="function") +def distributed_design(): + """Fixture for creating a DistributedDesign object.""" + return DistributedDesign(config["desktopVersion"]) diff --git a/tests/system/emit/conftest.py b/tests/system/emit/conftest.py index ebf9aaacda0..387cb536171 100644 --- a/tests/system/emit/conftest.py +++ b/tests/system/emit/conftest.py @@ -58,24 +58,15 @@ from ansys.aedt.core.aedt_logger import pyaedt_logger from ansys.aedt.core.desktop import Desktop from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.desktop_sessions import _desktop_sessions +from ansys.aedt.core.internal.desktop_sessions import ( + _desktop_sessions, +) from ansys.aedt.core.internal.filesystem import Scratch +from tests.conftest import config, apply_global_configuration local_path = Path(__file__).parent sys.path.append(str(local_path)) -# Initialize default desktop configuration -default_version = "2025.2" - -config = { - "desktopVersion": default_version, - "NonGraphical": True, - "NewThread": True, - "use_grpc": True, - "close_desktop": True, - "remove_lock": False, -} - # Check for the local config file, override defaults if found local_config_file = Path(local_path) / "local_config.json" if local_config_file.exists(): @@ -86,111 +77,5 @@ local_config = {} config.update(local_config) -NONGRAPHICAL = config["NonGraphical"] -desktop_version = config["desktopVersion"] -new_thread = config["NewThread"] -settings.use_grpc_api = config["use_grpc"] -close_desktop = config["close_desktop"] -remove_lock = config["remove_lock"] - -logger = pyaedt_logger - - -def generate_random_string(length): - characters = string.ascii_letters + string.digits - random_string = "".join(random.sample(characters, length)) - return random_string - - -def generate_random_ident(): - ident = "-" + generate_random_string(6) + "-" + generate_random_string(6) + "-" + generate_random_string(6) - return ident - - -@pytest.fixture(scope="session", autouse=True) -def init_scratch(): - test_folder_name = "unit_test" + generate_random_ident() - test_folder = Path(tempfile.gettempdir()) / test_folder_name - try: - os.makedirs(test_folder, mode=0o777) - except FileExistsError as e: - print(f"Failed to create {test_folder}. Reason: {e}") - - yield test_folder - - try: - shutil.rmtree(test_folder, ignore_errors=True) - except Exception as e: - print(f"Failed to delete {test_folder}. Reason: {e}") - - -@pytest.fixture(scope="module", autouse=True) -def local_scratch(init_scratch): - tmp_path = init_scratch - scratch = Scratch(tmp_path) - yield scratch - scratch.remove() - - -def _delete_objects(): - settings.remote_api = False - pyaedt_logger.remove_all_project_file_logger() - try: - del sys.modules["glob"] - except Exception: - logger.debug("Failed to delete glob module") - gc.collect() - - -@pytest.fixture(scope="module", autouse=True) -def desktop(local_scratch): - _delete_objects() - keys = list(_desktop_sessions.keys()) - for key in keys: - del _desktop_sessions[key] - d = Desktop(desktop_version, NONGRAPHICAL, new_thread) - d.odesktop.SetTempDirectory(str(local_scratch.path)) - d.disable_autosave() - if desktop_version > "2022.2": - d.odesktop.SetDesktopConfiguration("All") - d.odesktop.SetSchematicEnvironment(0) - yield d - pid = d.aedt_process_id - d.close_desktop() - time.sleep(1) - try: - os.kill(pid, 9) - except OSError: - pass - - -@pytest.fixture(scope="module") -def add_app(local_scratch): - def _method( - project_name=None, design_name=None, solution_type=None, application=None, subfolder="", just_open=False - ): - if project_name and not just_open: - example_project = Path(local_path) / "example_models" / subfolder / (project_name + ".aedt") - if example_project.exists(): - test_project = local_scratch.copyfile(str(example_project)) - elif example_project.with_suffix(".aedtz").exists(): - example_project = example_project.with_suffix(".aedtz") - test_project = local_scratch.copyfile(str(example_project)) - else: - test_project = Path(local_scratch.path) / (project_name + ".aedt") - elif project_name and just_open: - test_project = project_name - else: - test_project = None - if not application: - application = Emit - return application( - project=test_project, - design=design_name, - solution_type=solution_type, - version=desktop_version, - remove_lock=remove_lock, - non_graphical=NONGRAPHICAL, - ) +apply_global_configuration(config) - return _method diff --git a/tests/system/emit/test_emit.py b/tests/system/emit/test_emit.py index 69e09d40a76..4b4e255233c 100644 --- a/tests/system/emit/test_emit.py +++ b/tests/system/emit/test_emit.py @@ -38,7 +38,7 @@ import ansys.aedt.core from ansys.aedt.core.generic import constants as consts from ansys.aedt.core.generic.general_methods import is_linux -from tests.system.solvers.conftest import config +from tests.conftest import config # Prior to 2025R1, the Emit API supported Python 3.8,3.9,3.10,3.11 # Starting with 2025R1, the Emit API supports Python 3.10,3.11,3.12 diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py index e7f3dfb34be..cdfb6dc9282 100644 --- a/tests/system/extensions/conftest.py +++ b/tests/system/extensions/conftest.py @@ -43,55 +43,12 @@ import json import os -import random -import shutil -import string import sys -import tempfile -import pytest - -from ansys.aedt.core import Desktop -from ansys.aedt.core import Edb -from ansys.aedt.core import Hfss -from ansys.aedt.core.aedt_logger import pyaedt_logger -from ansys.aedt.core.generic.file_utils import generate_unique_name -from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.filesystem import Scratch - -settings.enable_local_log_file = False -settings.enable_global_log_file = False -settings.number_of_grpc_api_retries = 6 -settings.retry_n_times_time_interval = 0.5 -settings.enable_error_handler = False -settings.enable_desktop_logs = False -settings.desktop_launch_timeout = 180 -settings.release_on_exception = False -settings.wait_for_license = True -settings.enable_pandas_output = True +from tests.conftest import apply_global_configuration, config local_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(local_path) - -# Initialize default desktop configuration -default_version = "2025.2" - -os.environ["ANSYSEM_FEATURE_SS544753_ICEPAK_VIRTUALMESHREGION_PARADIGM_ENABLE"] = "1" - -config = { - "desktopVersion": default_version, - "NonGraphical": True, - "NewThread": True, - "skip_circuits": False, - "skip_modelithics": True, - "use_grpc": True, - "disable_sat_bounding_box": True, - "close_desktop": True, - "remove_lock": False, - "local_example_folder": None, - "use_local_example_data": False, -} - # Check for the local config file, override defaults if found local_config_file = os.path.join(local_path, "local_config.json") if os.path.exists(local_config_file): @@ -102,130 +59,4 @@ local_config = {} config.update(local_config) -NONGRAPHICAL = config["NonGraphical"] -settings.disable_bounding_box_sat = config["disable_sat_bounding_box"] -desktop_version = config["desktopVersion"] -new_thread = config["NewThread"] -settings.use_grpc_api = config["use_grpc"] - -logger = pyaedt_logger - -os.environ["PYAEDT_SCRIPT_VERSION"] = config["desktopVersion"] - - -def generate_random_string(length): - characters = string.ascii_letters + string.digits - random_string = "".join(random.sample(characters, length)) - return random_string - - -def generate_random_ident(): - ident = "-" + generate_random_string(6) + "-" + generate_random_string(6) + "-" + generate_random_string(6) - return ident - - -@pytest.fixture(scope="session", autouse=True) -def init_scratch(): - test_folder_name = "unit_test" + generate_random_ident() - test_folder = os.path.join(tempfile.gettempdir(), test_folder_name) - try: - os.makedirs(test_folder, mode=0o777) - except FileExistsError as e: - print(f"Failed to create {test_folder}. Reason: {e}") - - yield test_folder - - try: - shutil.rmtree(test_folder, ignore_errors=True) - except Exception as e: - print(f"Failed to delete {test_folder}. Reason: {e}") - - -@pytest.fixture(scope="module", autouse=True) -def local_scratch(init_scratch): - tmp_path = init_scratch - scratch = Scratch(tmp_path) - yield scratch - scratch.remove() - - -@pytest.fixture(scope="module", autouse=True) -def desktop(): - d = Desktop(desktop_version, NONGRAPHICAL, new_thread) - d.odesktop.SetTempDirectory(tempfile.gettempdir()) - d.disable_autosave() - - yield d - try: - d.close_desktop() - except Exception: - return False - - -@pytest.fixture(scope="module") -def add_app(local_scratch): - def _method( - project_name=None, design_name=None, solution_type=None, application=None, subfolder="", just_open=False - ): - if project_name and not just_open: - example_project = os.path.join(local_path, "example_models", subfolder, project_name + ".aedt") - example_folder = os.path.join(local_path, "example_models", subfolder, project_name + ".aedb") - if os.path.exists(example_project): - test_project = local_scratch.copyfile(example_project) - elif os.path.exists(example_project + "z"): - example_project = example_project + "z" - test_project = local_scratch.copyfile(example_project) - else: - test_project = os.path.join(local_scratch.path, project_name + ".aedt") - if os.path.exists(example_folder): - target_folder = os.path.join(local_scratch.path, project_name + ".aedb") - local_scratch.copyfolder(example_folder, target_folder) - elif project_name and just_open: - test_project = project_name - else: - test_project = None - if not application: - application = Hfss - return application( - project=test_project, - design=design_name, - solution_type=solution_type, - version=desktop_version, - ) - - return _method - - -@pytest.fixture(scope="module") -def test_project_file(local_scratch): - def _method(project_name=None, subfolder=None): - if subfolder: - project_file = os.path.join(local_path, "example_models", subfolder, project_name + ".aedt") - else: - project_file = os.path.join(local_scratch.path, project_name + ".aedt") - if os.path.exists(project_file): - return project_file - else: - return None - - return _method - - -@pytest.fixture(scope="module") -def add_edb(local_scratch): - def _method(project_name=None, subfolder=""): - if project_name: - example_folder = os.path.join(local_path, "example_models", subfolder, project_name + ".aedb") - if os.path.exists(example_folder): - target_folder = os.path.join(local_scratch.path, project_name + ".aedb") - local_scratch.copyfolder(example_folder, target_folder) - else: - target_folder = os.path.join(local_scratch.path, project_name + ".aedb") - else: - target_folder = os.path.join(local_scratch.path, generate_unique_name("TestEdb") + ".aedb") - return Edb( - target_folder, - edbversion=desktop_version, - ) - - return _method +apply_global_configuration(config) \ No newline at end of file diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py index 87bb7e0cc31..1714e306390 100644 --- a/tests/system/filter_solutions/conftest.py +++ b/tests/system/filter_solutions/conftest.py @@ -43,49 +43,13 @@ import json import os -import random -import shutil -import string import sys -import tempfile -import pytest - -from ansys.aedt.core.aedt_logger import pyaedt_logger -from ansys.aedt.core.filtersolutions import DistributedDesign -from ansys.aedt.core.filtersolutions import LumpedDesign -from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.filesystem import Scratch - -settings.enable_local_log_file = False -settings.enable_global_log_file = False -settings.number_of_grpc_api_retries = 6 -settings.retry_n_times_time_interval = 0.5 -settings.enable_error_handler = False -settings.enable_desktop_logs = False -settings.desktop_launch_timeout = 180 -settings.release_on_exception = False -settings.wait_for_license = True -settings.enable_pandas_output = True +from tests.conftest import apply_global_configuration, config local_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(local_path) -# Initialize default desktop configuration -default_version = "2025.2" - -config = { - "desktopVersion": default_version, - "NonGraphical": True, - "NewThread": True, - "skip_circuits": False, - "skip_modelithics": True, - "use_grpc": True, - "disable_sat_bounding_box": True, - "local_example_folder": None, - "use_local_example_data": False, -} - # Check for the local config file, override defaults if found local_config_file = os.path.join(local_path, "local_config.json") if os.path.exists(local_config_file): @@ -96,59 +60,4 @@ local_config = {} config.update(local_config) -NONGRAPHICAL = config["NonGraphical"] -settings.disable_bounding_box_sat = config["disable_sat_bounding_box"] -desktop_version = config["desktopVersion"] -new_thread = config["NewThread"] -settings.use_grpc_api = config["use_grpc"] -settings.local_example_folder = config["local_example_folder"] - -logger = pyaedt_logger - - -def generate_random_string(length): - characters = string.ascii_letters + string.digits - random_string = "".join(random.sample(characters, length)) - return random_string - - -def generate_random_ident(): - ident = "-" + generate_random_string(6) + "-" + generate_random_string(6) + "-" + generate_random_string(6) - return ident - - -@pytest.fixture(scope="session", autouse=True) -def init_scratch(): - test_folder_name = "unit_test" + generate_random_ident() - test_folder = os.path.join(tempfile.gettempdir(), test_folder_name) - try: - os.makedirs(test_folder, mode=0o777) - except FileExistsError as e: - print(f"Failed to create {test_folder}. Reason: {e}") - - yield test_folder - - try: - shutil.rmtree(test_folder, ignore_errors=True) - except Exception as e: - print(f"Failed to delete {test_folder}. Reason: {e}") - - -@pytest.fixture(scope="module", autouse=True) -def local_scratch(init_scratch): - tmp_path = init_scratch - scratch = Scratch(tmp_path) - yield scratch - scratch.remove() - - -@pytest.fixture(scope="function") -def lumped_design(): - """Fixture for creating a LumpedDesign object.""" - return LumpedDesign(config["desktopVersion"]) - - -@pytest.fixture(scope="function") -def distributed_design(): - """Fixture for creating a DistributedDesign object.""" - return DistributedDesign(config["desktopVersion"]) +apply_global_configuration(config) diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index 30ce4ac4ed8..74f858142bc 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -44,53 +44,25 @@ import gc import json import os -import random -import shutil -import string import sys import tempfile import time import pytest -from ansys.aedt.core import Edb -from ansys.aedt.core import Hfss from ansys.aedt.core.aedt_logger import pyaedt_logger from ansys.aedt.core.desktop import Desktop -from ansys.aedt.core.generic.file_utils import generate_unique_name from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.desktop_sessions import _desktop_sessions -from ansys.aedt.core.internal.filesystem import Scratch -from tests import TESTS_GENERAL_PATH - -settings.enable_local_log_file = False -settings.enable_global_log_file = False -settings.number_of_grpc_api_retries = 6 -settings.retry_n_times_time_interval = 0.5 -settings.enable_error_handler = False -settings.enable_desktop_logs = False -settings.desktop_launch_timeout = 180 -settings.release_on_exception = False -settings.wait_for_license = True -settings.enable_pandas_output = True -settings.use_local_example_data = False +from ansys.aedt.core.internal.desktop_sessions import ( + _desktop_sessions, +) +from tests.conftest import apply_global_configuration +from tests.conftest import config +from tests.conftest import logger local_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(local_path) -# Initialize default desktop configuration -default_version = "2025.2" - -config = { - "desktopVersion": default_version, - "NonGraphical": True, - "NewThread": True, - "skip_circuits": False, - "use_grpc": True, - "disable_sat_bounding_box": True, - "use_local_example_data": False, -} - # Check for the local config file, override defaults if found local_config_file = os.path.join(local_path, "local_config.json") if os.path.exists(local_config_file): @@ -101,28 +73,7 @@ local_config = {} config.update(local_config) -NONGRAPHICAL = config["NonGraphical"] -settings.disable_bounding_box_sat = config["disable_sat_bounding_box"] -desktop_version = config["desktopVersion"] -new_thread = config["NewThread"] -settings.use_grpc_api = config["use_grpc"] -settings.objects_lazy_load = False -settings.use_local_example_data = config["use_local_example_data"] -if settings.use_local_example_data: - settings.local_example_folder = config["local_example_folder"] - -logger = pyaedt_logger - - -def generate_random_string(length): - characters = string.ascii_letters + string.digits - random_string = "".join(random.sample(characters, length)) - return random_string - - -def generate_random_ident(): - ident = "-" + generate_random_string(6) + "-" + generate_random_string(6) + "-" + generate_random_string(6) - return ident +apply_global_configuration(config) def _delete_objects(): @@ -135,41 +86,16 @@ def _delete_objects(): gc.collect() -@pytest.fixture(scope="session", autouse=True) -def init_scratch(): - test_folder_name = "unit_test" + generate_random_ident() - test_folder = os.path.join(tempfile.gettempdir(), test_folder_name) - try: - os.makedirs(test_folder, mode=0o777) - except FileExistsError as e: - print(f"Failed to create {test_folder}. Reason: {e}") - - yield test_folder - - try: - shutil.rmtree(test_folder, ignore_errors=True) - except Exception as e: - print(f"Failed to delete {test_folder}. Reason: {e}") - - -@pytest.fixture(scope="module", autouse=True) -def local_scratch(init_scratch): - tmp_path = init_scratch - scratch = Scratch(tmp_path) - yield scratch - scratch.remove() - - @pytest.fixture(scope="module", autouse=True) def desktop(): _delete_objects() keys = list(_desktop_sessions.keys()) for key in keys: del _desktop_sessions[key] - d = Desktop(desktop_version, NONGRAPHICAL, new_thread) + d = Desktop(config["desktopVersion"], config["NonGraphical"], config["NewThread"]) d.odesktop.SetTempDirectory(tempfile.gettempdir()) d.disable_autosave() - if desktop_version > "2022.2": + if config["desktopVersion"] > "2022.2": d.odesktop.SetDesktopConfiguration("All") d.odesktop.SetSchematicEnvironment(0) yield d @@ -181,77 +107,3 @@ def desktop(): except OSError: pass - -@pytest.fixture(scope="module") -def add_app(local_scratch): - def _method( - project_name=None, design_name=None, solution_type=None, application=None, subfolder="", just_open=False - ): - if project_name and not just_open: - example_project = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedt") - example_folder = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedb") - if os.path.exists(example_project): - # Copy unit test project to scratch folder. Return full file path to the project without extension. - test_project = local_scratch.copyfile(example_project) - elif os.path.exists(example_project + "z"): - example_project = example_project + "z" - test_project = local_scratch.copyfile(example_project) - else: - test_project = os.path.join(local_scratch.path, project_name + ".aedt") - if os.path.exists(example_folder): - target_folder = os.path.join(local_scratch.path, project_name + ".aedb") - local_scratch.copyfolder(example_folder, target_folder) - elif project_name and just_open: - test_project = project_name - else: - test_project = None - if not application: - application = Hfss - - args = { - "project": test_project, - "design": design_name, - "version": desktop_version, - "non_graphical": NONGRAPHICAL, - "remove_lock": True, - } - if solution_type: - args["solution_type"] = solution_type - return application(**args) - - return _method - - -@pytest.fixture(scope="module") -def test_project_file(local_scratch): - def _method(project_name=None, subfolder=None): - if subfolder: - project_file = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedt") - else: - project_file = os.path.join(local_scratch.path, project_name + ".aedt") - if os.path.exists(project_file): - return project_file - else: - return None - - return _method - - -@pytest.fixture(scope="module") -def add_edb(local_scratch): - def _method(project_name=None, subfolder=""): - if project_name: - example_folder = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedb") - if os.path.exists(example_folder): - target_folder = os.path.join(local_scratch.path, project_name + ".aedb") - local_scratch.copyfolder(example_folder, target_folder) - else: - target_folder = os.path.join(local_scratch.path, project_name + ".aedb") - else: - target_folder = os.path.join(local_scratch.path, generate_unique_name("TestEdb") + ".aedb") - return Edb( - target_folder, - edbversion=desktop_version, - ) - - return _method diff --git a/tests/system/general/test_01_3dlayout_edb.py b/tests/system/general/test_01_3dlayout_edb.py index 5d87f2eb7c9..3aa2e729bc1 100644 --- a/tests/system/general/test_01_3dlayout_edb.py +++ b/tests/system/general/test_01_3dlayout_edb.py @@ -30,7 +30,7 @@ from ansys.aedt.core import Hfss3dLayout from ansys.aedt.core.modeler.pcb.object_3d_layout import Components3DLayout from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_subfolder = "T40" original_project_name = "ANSYS-HSD_V1" diff --git a/tests/system/general/test_01_Design.py b/tests/system/general/test_01_Design.py index 35bddbae88a..afe7d08cb41 100644 --- a/tests/system/general/test_01_Design.py +++ b/tests/system/general/test_01_Design.py @@ -37,8 +37,8 @@ from ansys.aedt.core.generic.general_methods import is_linux from ansys.aedt.core.generic.general_methods import settings from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config -from tests.system.general.conftest import desktop_version +from tests.conftest import config +from tests.conftest import desktop_version test_subfolder = "T01" if config["desktopVersion"] > "2022.2": diff --git a/tests/system/general/test_01_configuration_files.py b/tests/system/general/test_01_configuration_files.py index 10afac99ebf..4fd8a40db9e 100644 --- a/tests/system/general/test_01_configuration_files.py +++ b/tests/system/general/test_01_configuration_files.py @@ -33,7 +33,7 @@ from ansys.aedt.core import Q2d from ansys.aedt.core import Q3d from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_project_name = "dm boundary test" test_field_name = "Potter_Horn" diff --git a/tests/system/general/test_02_3D_modeler.py b/tests/system/general/test_02_3D_modeler.py index 9fa2d8b009f..2793fcb9431 100644 --- a/tests/system/general/test_02_3D_modeler.py +++ b/tests/system/general/test_02_3D_modeler.py @@ -37,7 +37,7 @@ from ansys.aedt.core.modeler.cad.primitives import CoordinateSystem as cs from ansys.aedt.core.modeler.cad.primitives import PolylineSegment from ansys.aedt.core.modeler.geometry_operators import GeometryOperators as go -from tests.system.general.conftest import config +from tests.conftest import config test_subfolder = "T02" if config["desktopVersion"] > "2022.2": diff --git a/tests/system/general/test_03_Materials.py b/tests/system/general/test_03_Materials.py index 91d5627e212..b19e92a71ba 100644 --- a/tests/system/general/test_03_Materials.py +++ b/tests/system/general/test_03_Materials.py @@ -35,7 +35,7 @@ from ansys.aedt.core.modules.material import MatProperties from ansys.aedt.core.modules.material import SurfMatProperties from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_subfolder = "T03" diff --git a/tests/system/general/test_04_SBR.py b/tests/system/general/test_04_SBR.py index 5bdca9e0012..2dbd809695a 100644 --- a/tests/system/general/test_04_SBR.py +++ b/tests/system/general/test_04_SBR.py @@ -35,7 +35,7 @@ from ansys.aedt.core.generic.settings import is_linux from ansys.aedt.core.internal.errors import AEDTRuntimeError from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import desktop_version +from tests.conftest import desktop_version if desktop_version > "2022.2": test_project_name = "Cassegrain_231" diff --git a/tests/system/general/test_05_Mesh.py b/tests/system/general/test_05_Mesh.py index e0cf4e5296a..e60b54c29ac 100644 --- a/tests/system/general/test_05_Mesh.py +++ b/tests/system/general/test_05_Mesh.py @@ -26,8 +26,8 @@ from ansys.aedt.core import Maxwell3d from ansys.aedt.core.generic.constants import Plane -from tests.system.general.conftest import config -from tests.system.general.conftest import desktop_version +from tests.conftest import config +from tests.conftest import desktop_version @pytest.fixture(scope="class") diff --git a/tests/system/general/test_06_MessageManager.py b/tests/system/general/test_06_MessageManager.py index c3bfe844b79..2fd35db7c66 100644 --- a/tests/system/general/test_06_MessageManager.py +++ b/tests/system/general/test_06_MessageManager.py @@ -30,7 +30,7 @@ from ansys.aedt.core import Icepak from ansys.aedt.core.aedt_logger import AedtLogger from ansys.aedt.core.generic.settings import settings -from tests.system.general.conftest import config +from tests.conftest import config LOGGER = logging.getLogger(__name__) diff --git a/tests/system/general/test_08_Primitives3D.py b/tests/system/general/test_08_Primitives3D.py index eb73164913d..64c06bab3cb 100644 --- a/tests/system/general/test_08_Primitives3D.py +++ b/tests/system/general/test_08_Primitives3D.py @@ -40,7 +40,7 @@ from ansys.aedt.core.modeler.cad.primitives import PolylineSegment from ansys.aedt.core.modeler.geometry_operators import GeometryOperators from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test = sys.modules.keys() diff --git a/tests/system/general/test_09_VariableManager.py b/tests/system/general/test_09_VariableManager.py index f0e6fb22d73..454e20705ef 100644 --- a/tests/system/general/test_09_VariableManager.py +++ b/tests/system/general/test_09_VariableManager.py @@ -32,7 +32,7 @@ from ansys.aedt.core.generic.numbers_utils import decompose_variable_value from ansys.aedt.core.generic.numbers_utils import is_close from ansys.aedt.core.modeler.geometry_operators import GeometryOperators -from tests.system.general.conftest import desktop_version +from tests.conftest import desktop_version @pytest.fixture(scope="class") diff --git a/tests/system/general/test_11_Setup.py b/tests/system/general/test_11_Setup.py index ebeefd625b3..d9caa52ab68 100644 --- a/tests/system/general/test_11_Setup.py +++ b/tests/system/general/test_11_Setup.py @@ -28,7 +28,7 @@ from ansys.aedt.core import Circuit from ansys.aedt.core.generic.constants import Setups -from tests.system.general.conftest import desktop_version +from tests.conftest import desktop_version test_subfolder = "T11" if desktop_version > "2022.2": diff --git a/tests/system/general/test_13_LoadAEDTFile.py b/tests/system/general/test_13_LoadAEDTFile.py index 97d5956d9ee..8f6ae3ffe34 100644 --- a/tests/system/general/test_13_LoadAEDTFile.py +++ b/tests/system/general/test_13_LoadAEDTFile.py @@ -32,7 +32,7 @@ from ansys.aedt.core.internal.load_aedt_file import load_entire_aedt_file from ansys.aedt.core.internal.load_aedt_file import load_keyword_in_aedt_file from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_subfolder = "T13" if config["desktopVersion"] > "2022.2": diff --git a/tests/system/general/test_14_AedtLogger.py b/tests/system/general/test_14_AedtLogger.py index 47f03a8119b..fb1a0bb0fca 100644 --- a/tests/system/general/test_14_AedtLogger.py +++ b/tests/system/general/test_14_AedtLogger.py @@ -34,7 +34,7 @@ from ansys.aedt.core.aedt_logger import AedtLogger from ansys.aedt.core.generic.settings import settings -from tests.system.general.conftest import config +from tests.conftest import config settings.enable_desktop_logs = True diff --git a/tests/system/general/test_20_HFSS.py b/tests/system/general/test_20_HFSS.py index 51d9486b487..9d68851c391 100644 --- a/tests/system/general/test_20_HFSS.py +++ b/tests/system/general/test_20_HFSS.py @@ -36,8 +36,8 @@ from ansys.aedt.core.visualization.advanced.misc import convert_nearfield_data from tests import TESTS_GENERAL_PATH from tests import TESTS_SOLVERS_PATH -from tests.system.general.conftest import config -from tests.system.general.conftest import settings +from tests.conftest import config +from tests.conftest import settings small_number = 1e-10 # Used for checking equivalence. diff --git a/tests/system/general/test_21_Circuit.py b/tests/system/general/test_21_Circuit.py index bca7492e4d0..648ad5f4d6e 100644 --- a/tests/system/general/test_21_Circuit.py +++ b/tests/system/general/test_21_Circuit.py @@ -33,7 +33,7 @@ from ansys.aedt.core.generic.settings import is_linux from ansys.aedt.core.internal.errors import AEDTRuntimeError from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_subfolder = "T21" diff --git a/tests/system/general/test_22_Circuit_DynamicLink.py b/tests/system/general/test_22_Circuit_DynamicLink.py index f1ba6b74725..3a869551dfc 100644 --- a/tests/system/general/test_22_Circuit_DynamicLink.py +++ b/tests/system/general/test_22_Circuit_DynamicLink.py @@ -31,7 +31,7 @@ from ansys.aedt.core import Q3d from ansys.aedt.core.generic.settings import is_linux from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_subfloder = "T22" test_project_name = "Dynamic_Link" diff --git a/tests/system/general/test_27_Maxwell2D.py b/tests/system/general/test_27_Maxwell2D.py index f924bc57f49..97bc4edb170 100644 --- a/tests/system/general/test_27_Maxwell2D.py +++ b/tests/system/general/test_27_Maxwell2D.py @@ -33,7 +33,7 @@ from ansys.aedt.core.generic.constants import SolutionsMaxwell2D from ansys.aedt.core.internal.errors import AEDTRuntimeError from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_subfolder = "TMaxwell" diff --git a/tests/system/general/test_28_Maxwell3D.py b/tests/system/general/test_28_Maxwell3D.py index 8ef53537d4e..aac6be6f16d 100644 --- a/tests/system/general/test_28_Maxwell3D.py +++ b/tests/system/general/test_28_Maxwell3D.py @@ -37,8 +37,8 @@ from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.modeler.geometry_operators import GeometryOperators from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config -from tests.system.solvers.conftest import desktop_version +from tests.conftest import config +from tests.conftest import desktop_version try: from IPython.display import Image diff --git a/tests/system/general/test_30_Q2D.py b/tests/system/general/test_30_Q2D.py index a4b2e195b0d..e145af36b87 100644 --- a/tests/system/general/test_30_Q2D.py +++ b/tests/system/general/test_30_Q2D.py @@ -31,7 +31,7 @@ from ansys.aedt.core.generic.constants import MatrixOperationsQ2D from ansys.aedt.core.internal.errors import AEDTRuntimeError from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_project_name = "coax_Q2D" test_subfolder = "T30" diff --git a/tests/system/general/test_34_TwinBuilder.py b/tests/system/general/test_34_TwinBuilder.py index cb836af1b63..f2da2790208 100644 --- a/tests/system/general/test_34_TwinBuilder.py +++ b/tests/system/general/test_34_TwinBuilder.py @@ -31,10 +31,10 @@ from ansys.aedt.core import TwinBuilder from ansys.aedt.core.generic.general_methods import is_linux from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import NONGRAPHICAL -from tests.system.general.conftest import config -from tests.system.general.conftest import desktop_version -from tests.system.general.conftest import new_thread +from tests.conftest import NONGRAPHICAL +from tests.conftest import config +from tests.conftest import desktop_version +from tests.conftest import new_thread test_subfolder = "T34" diff --git a/tests/system/general/test_36_Q2D_PostProcessing.py b/tests/system/general/test_36_Q2D_PostProcessing.py index f7eb52e65f1..127223be3c6 100644 --- a/tests/system/general/test_36_Q2D_PostProcessing.py +++ b/tests/system/general/test_36_Q2D_PostProcessing.py @@ -27,7 +27,7 @@ import pytest from ansys.aedt.core import Q2d -from tests.system.general.conftest import config +from tests.conftest import config test_subfolder = "T36" diff --git a/tests/system/general/test_41_3dlayout_modeler.py b/tests/system/general/test_41_3dlayout_modeler.py index 03cad3a2a40..07ead07c3a3 100644 --- a/tests/system/general/test_41_3dlayout_modeler.py +++ b/tests/system/general/test_41_3dlayout_modeler.py @@ -36,7 +36,7 @@ from ansys.aedt.core.generic.general_methods import is_linux from ansys.aedt.core.visualization.plot.pdf import AnsysReport from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_subfolder = "T41" test_project_name = "Test_RadioBoard" diff --git a/tests/system/general/test_43_CableModeling.py b/tests/system/general/test_43_CableModeling.py index 09e39183c49..c12a4f8575d 100644 --- a/tests/system/general/test_43_CableModeling.py +++ b/tests/system/general/test_43_CableModeling.py @@ -29,7 +29,7 @@ from ansys.aedt.core.generic.file_utils import read_json from ansys.aedt.core.modules.cable_modeling import Cable from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config if config["desktopVersion"] > "2022.2": project_name = "cable_modeling_231" diff --git a/tests/system/general/test_47_CircuitNetlist.py b/tests/system/general/test_47_CircuitNetlist.py index e4d80ed75a0..6da92f1629d 100644 --- a/tests/system/general/test_47_CircuitNetlist.py +++ b/tests/system/general/test_47_CircuitNetlist.py @@ -28,7 +28,7 @@ from ansys.aedt.core import CircuitNetlist from ansys.aedt.core.generic.general_methods import is_linux -from tests.system.general.conftest import config +from tests.conftest import config netlist = "netlist" test_subfolder = "T47" diff --git a/tests/system/general/test_98_Icepak.py b/tests/system/general/test_98_Icepak.py index 72d15d22a38..6874debe50e 100644 --- a/tests/system/general/test_98_Icepak.py +++ b/tests/system/general/test_98_Icepak.py @@ -41,7 +41,7 @@ from ansys.aedt.core.visualization.post.field_data import FolderPlotSettings from ansys.aedt.core.visualization.post.field_data import SpecifiedScale from tests import TESTS_GENERAL_PATH -from tests.system.general.conftest import config +from tests.conftest import config test_subfolder = "T98" board_3dl = "FilterBoard_H3DL" diff --git a/tests/system/general/test_launch_desktop.py b/tests/system/general/test_launch_desktop.py index f7c2a2d4d50..9eea30084d5 100644 --- a/tests/system/general/test_launch_desktop.py +++ b/tests/system/general/test_launch_desktop.py @@ -42,7 +42,7 @@ from ansys.aedt.core.generic.constants import SolutionsMechanical from ansys.aedt.core.generic.general_methods import is_linux from ansys.aedt.core.generic.settings import settings -from tests.system.general.conftest import config +from tests.conftest import config settings.lazy_load = False settings.wait_for_license = True diff --git a/tests/system/solvers/conftest.py b/tests/system/solvers/conftest.py index 4d0625659be..f463614ca66 100644 --- a/tests/system/solvers/conftest.py +++ b/tests/system/solvers/conftest.py @@ -23,80 +23,27 @@ # SOFTWARE. """ -Unit Test Configuration Module -------------------------------- +System Solvers Test Configuration +--------------------------------- -Description -=========== - -This module contains the configuration and fixture for the pytest-based unit tests for PyAEDT. - -The default configuration can be changed by placing a file called local_config.json in the same -directory as this module. An example of the contents of local_config.json -{ - "desktopVersion": "2022.2", - "NonGraphical": false, - "NewThread": false, -} +This conftest.py contains configurations specific to system solver tests. +It extends the top-level tests/conftest.py with solver-specific fixtures. +Local configurations can override defaults by creating a local_config.json +file in this directory with solver-specific parameters only. """ import json import os -from pathlib import Path -import random -import shutil -import string import sys -import tempfile - -import pytest - -from ansys.aedt.core import Desktop -from ansys.aedt.core import Edb -from ansys.aedt.core import Hfss -from ansys.aedt.core.aedt_logger import pyaedt_logger -from ansys.aedt.core.generic.file_utils import generate_unique_name -from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.filesystem import Scratch - -settings.enable_local_log_file = False -settings.enable_global_log_file = False -settings.number_of_grpc_api_retries = 6 -settings.retry_n_times_time_interval = 0.5 -settings.enable_error_handler = False -settings.enable_desktop_logs = False -settings.desktop_launch_timeout = 180 -settings.release_on_exception = False -settings.wait_for_license = True -settings.enable_pandas_output = True -settings.use_local_example_data = False +from tests.conftest import config, apply_global_configuration -local_path = Path(__file__).parent -sys.path.append(str(local_path)) - -# Initialize default desktop configuration -default_version = "2025.2" - -os.environ["ANSYSEM_FEATURE_SS544753_ICEPAK_VIRTUALMESHREGION_PARADIGM_ENABLE"] = "1" - -config = { - "desktopVersion": default_version, - "NonGraphical": True, - "NewThread": True, - "skip_circuits": False, - "skip_modelithics": True, - "use_grpc": True, - "disable_sat_bounding_box": True, - "close_desktop": True, - "remove_lock": False, - "local_example_folder": None, - "use_local_example_data": False, -} +local_path = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(local_path) # Check for the local config file, override defaults if found -local_config_file = Path(local_path) / "local_config.json" -if local_config_file.exists(): +local_config_file = os.path.join(local_path, "local_config.json") +if os.path.exists(local_config_file): try: with open(local_config_file) as f: local_config = json.load(f) @@ -104,136 +51,4 @@ local_config = {} config.update(local_config) -NONGRAPHICAL = config["NonGraphical"] -settings.disable_bounding_box_sat = config["disable_sat_bounding_box"] -desktop_version = config["desktopVersion"] -new_thread = config["NewThread"] -settings.use_grpc_api = config["use_grpc"] -close_desktop = config["close_desktop"] -remove_lock = config["remove_lock"] -settings.use_local_example_data = config["use_local_example_data"] -if settings.use_local_example_data: - settings.local_example_folder = config["local_example_folder"] - -logger = pyaedt_logger - - -def generate_random_string(length): - characters = string.ascii_letters + string.digits - random_string = "".join(random.sample(characters, length)) - return random_string - - -def generate_random_ident(): - ident = "-" + generate_random_string(6) + "-" + generate_random_string(6) + "-" + generate_random_string(6) - return ident - - -@pytest.fixture(scope="session", autouse=True) -def init_scratch(): - test_folder_name = "unit_test" + generate_random_ident() - test_folder = Path(tempfile.gettempdir()) / test_folder_name - try: - os.makedirs(test_folder, mode=0o777) - except FileExistsError as e: - print(f"Failed to create {test_folder}. Reason: {e}") - - yield test_folder - - try: - shutil.rmtree(test_folder, ignore_errors=True) - except Exception as e: - print(f"Failed to delete {test_folder}. Reason: {e}") - - -@pytest.fixture(scope="module", autouse=True) -def local_scratch(init_scratch): - tmp_path = init_scratch - scratch = Scratch(tmp_path) - yield scratch - scratch.remove() - - -@pytest.fixture(scope="module", autouse=True) -def desktop(): - d = Desktop(desktop_version, NONGRAPHICAL, new_thread) - d.odesktop.SetTempDirectory(tempfile.gettempdir()) - d.disable_autosave() - - yield d - - if close_desktop: - d.close_desktop() - else: - d.release_desktop(close_projects=True, close_on_exit=False) - - -@pytest.fixture(scope="module") -def add_app(local_scratch): - def _method( - project_name=None, design_name=None, solution_type=None, application=None, subfolder="", just_open=False - ): - if project_name and not just_open: - example_project = Path(local_path) / "example_models" / subfolder / (project_name + ".aedt") - example_folder = Path(local_path) / "example_models" / subfolder / (project_name + ".aedb") - if example_project.exists(): - test_project = local_scratch.copyfile(str(example_project)) - elif example_project.with_suffix(".aedtz").exists(): - example_project = example_project.with_suffix(".aedtz") - test_project = local_scratch.copyfile(str(example_project)) - else: - test_project = Path(local_scratch.path) / (project_name + ".aedt") - if example_folder.exists(): - target_folder = local_scratch.path / (project_name + ".aedb") - local_scratch.copyfolder(example_folder, target_folder) - elif project_name and just_open: - test_project = project_name - else: - test_project = None - if not application: - application = Hfss - return application( - project=test_project, - design=design_name, - solution_type=solution_type, - version=desktop_version, - remove_lock=remove_lock, - non_graphical=NONGRAPHICAL, - ) - - return _method - - -@pytest.fixture(scope="module") -def test_project_file(local_scratch): - def _method(project_name=None, subfolder=None): - if subfolder: - project_file = Path(local_path) / "example_models" / subfolder / (project_name + ".aedt") - else: - project_file = Path(local_scratch.path) / (project_name + ".aedt") - if project_file.exists(): - return project_file - else: - return None - - return _method - - -@pytest.fixture(scope="module") -def add_edb(local_scratch): - def _method(project_name=None, subfolder=""): - if project_name: - example_folder = Path(local_path) / "example_models" / subfolder / (project_name + ".aedb") - if example_folder.exists(): - target_folder = local_scratch.path / (project_name + ".aedb") - local_scratch.copyfolder(example_folder, target_folder) - else: - target_folder = local_scratch.path / (project_name + ".aedb") - else: - target_folder = local_scratch.path / (generate_unique_name("TestEdb") + ".aedb") - return Edb( - target_folder, - edbversion=desktop_version, - ) - - return _method +apply_global_configuration(config) diff --git a/tests/system/solvers/sequential/test_3dlayout_dcir.py b/tests/system/solvers/sequential/test_3dlayout_dcir.py index b7aba1306b8..45c7ad3f22e 100644 --- a/tests/system/solvers/sequential/test_3dlayout_dcir.py +++ b/tests/system/solvers/sequential/test_3dlayout_dcir.py @@ -26,7 +26,7 @@ from ansys.aedt.core import Hfss3dLayout from ansys.aedt.core.generic.settings import is_linux -from tests.system.solvers.conftest import config +from tests.conftest import config test_subfolder = "dcir" original_project_name = "ANSYS-HSD_V1" diff --git a/tests/system/solvers/sequential/test_icepak_3d_component.py b/tests/system/solvers/sequential/test_icepak_3d_component.py index 8109f55a515..235cabaa584 100644 --- a/tests/system/solvers/sequential/test_icepak_3d_component.py +++ b/tests/system/solvers/sequential/test_icepak_3d_component.py @@ -29,7 +29,7 @@ from ansys.aedt.core import Icepak from ansys.aedt.core.generic.constants import Plane from ansys.aedt.core.modules.boundary.layout_boundary import NativeComponentObject -from tests.system.solvers.conftest import config +from tests.conftest import config test_subfolder = "icepak_board" original_project_name = "FilterBoard" diff --git a/tests/system/solvers/test_00_analyze.py b/tests/system/solvers/test_00_analyze.py index a1b308adeca..15eda7e4542 100644 --- a/tests/system/solvers/test_00_analyze.py +++ b/tests/system/solvers/test_00_analyze.py @@ -41,8 +41,8 @@ from ansys.aedt.core.modules.profile import Profiles from ansys.aedt.core.modules.profile import SimulationProfile from ansys.aedt.core.visualization.post.spisim import SpiSim -from tests.system.solvers.conftest import desktop_version -from tests.system.solvers.conftest import local_path +from tests.conftest import desktop_version +from tests.conftest import local_path sbr_platform_name = "satellite_231" icepak_solved_name = "icepak_summary_solved" diff --git a/tests/system/solvers/test_01_pdf.py b/tests/system/solvers/test_01_pdf.py index 3978309ef45..caa93539437 100644 --- a/tests/system/solvers/test_01_pdf.py +++ b/tests/system/solvers/test_01_pdf.py @@ -33,8 +33,8 @@ from ansys.aedt.core.visualization.plot.pdf import AnsysReport from ansys.aedt.core.visualization.post.compliance import VirtualCompliance from ansys.aedt.core.visualization.post.compliance import VirtualComplianceGenerator -from tests.system.solvers.conftest import desktop_version -from tests.system.solvers.conftest import local_path +from tests.conftest import desktop_version +from tests.conftest import local_path tol = 1e-12 test_project_name = "ANSYS-HSD_V1_0_test" diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py index bb6cd5c344f..6d27ec0a4f2 100644 --- a/tests/system/visualization/conftest.py +++ b/tests/system/visualization/conftest.py @@ -43,57 +43,13 @@ import json import os -import random -import shutil -import string import sys -import tempfile -import pytest - -from ansys.aedt.core import Desktop -from ansys.aedt.core import Edb -from ansys.aedt.core import Hfss -from ansys.aedt.core.aedt_logger import pyaedt_logger -from ansys.aedt.core.filtersolutions import DistributedDesign -from ansys.aedt.core.filtersolutions import LumpedDesign -from ansys.aedt.core.generic.file_utils import generate_unique_name -from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.filesystem import Scratch - -settings.enable_local_log_file = False -settings.enable_global_log_file = False -settings.number_of_grpc_api_retries = 6 -settings.retry_n_times_time_interval = 0.5 -settings.enable_error_handler = False -settings.enable_desktop_logs = False -settings.desktop_launch_timeout = 180 -settings.release_on_exception = False -settings.wait_for_license = True -settings.enable_pandas_output = True -settings.use_local_example_data = False +from tests.conftest import config, apply_global_configuration local_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(local_path) -# Initialize default desktop configuration -default_version = "2025.2" - -os.environ["ANSYSEM_FEATURE_SS544753_ICEPAK_VIRTUALMESHREGION_PARADIGM_ENABLE"] = "1" - -config = { - "desktopVersion": default_version, - "NonGraphical": True, - "NewThread": True, - "skip_circuits": False, - "skip_modelithics": True, - "use_grpc": True, - "disable_sat_bounding_box": True, - "close_desktop": True, - "remove_lock": False, - "local_example_folder": None, - "use_local_example_data": False, -} # Check for the local config file, override defaults if found local_config_file = os.path.join(local_path, "local_config.json") @@ -105,148 +61,4 @@ local_config = {} config.update(local_config) -NONGRAPHICAL = config["NonGraphical"] -settings.disable_bounding_box_sat = config["disable_sat_bounding_box"] -desktop_version = config["desktopVersion"] -new_thread = config["NewThread"] -settings.use_grpc_api = config["use_grpc"] -if settings.use_local_example_data: - settings.local_example_folder = config["local_example_folder"] -close_desktop = config["close_desktop"] -remove_lock = config["remove_lock"] - -logger = pyaedt_logger - - -def generate_random_string(length): - characters = string.ascii_letters + string.digits - random_string = "".join(random.sample(characters, length)) - return random_string - - -def generate_random_ident(): - ident = "-" + generate_random_string(6) + "-" + generate_random_string(6) + "-" + generate_random_string(6) - return ident - - -@pytest.fixture(scope="session", autouse=True) -def init_scratch(): - test_folder_name = "unit_test" + generate_random_ident() - test_folder = os.path.join(tempfile.gettempdir(), test_folder_name) - try: - os.makedirs(test_folder, mode=0o777) - except FileExistsError as e: - print(f"Failed to create {test_folder}. Reason: {e}") - - yield test_folder - - try: - shutil.rmtree(test_folder, ignore_errors=True) - except Exception as e: - print(f"Failed to delete {test_folder}. Reason: {e}") - - -@pytest.fixture(scope="module", autouse=True) -def local_scratch(init_scratch): - tmp_path = init_scratch - scratch = Scratch(tmp_path) - yield scratch - scratch.remove() - - -@pytest.fixture(scope="module", autouse=True) -def desktop(): - d = Desktop(desktop_version, NONGRAPHICAL, new_thread) - d.odesktop.SetTempDirectory(tempfile.gettempdir()) - d.disable_autosave() - - yield d - try: - if close_desktop: - d.close_desktop() - else: - d.release_desktop(close_projects=True, close_on_exit=False) - except Exception: - return False - - -@pytest.fixture(scope="module") -def add_app(local_scratch): - def _method( - project_name=None, design_name=None, solution_type=None, application=None, subfolder="", just_open=False - ): - if project_name and not just_open: - example_project = os.path.join(local_path, "example_models", subfolder, project_name + ".aedt") - example_folder = os.path.join(local_path, "example_models", subfolder, project_name + ".aedb") - if os.path.exists(example_project): - test_project = local_scratch.copyfile(example_project) - elif os.path.exists(example_project + "z"): - example_project = example_project + "z" - test_project = local_scratch.copyfile(example_project) - else: - test_project = os.path.join(local_scratch.path, project_name + ".aedt") - if os.path.exists(example_folder): - target_folder = os.path.join(local_scratch.path, project_name + ".aedb") - local_scratch.copyfolder(example_folder, target_folder) - elif project_name and just_open: - test_project = project_name - else: - test_project = None - if not application: - application = Hfss - return application( - project=test_project, - design=design_name, - solution_type=solution_type, - version=desktop_version, - remove_lock=remove_lock, - ) - - return _method - - -@pytest.fixture(scope="module") -def test_project_file(local_scratch): - def _method(project_name=None, subfolder=None): - if subfolder: - project_file = os.path.join(local_path, "example_models", subfolder, project_name + ".aedt") - else: - project_file = os.path.join(local_scratch.path, project_name + ".aedt") - if os.path.exists(project_file): - return project_file - else: - return None - - return _method - - -@pytest.fixture(scope="module") -def add_edb(local_scratch): - def _method(project_name=None, subfolder=""): - if project_name: - example_folder = os.path.join(local_path, "example_models", subfolder, project_name + ".aedb") - if os.path.exists(example_folder): - target_folder = os.path.join(local_scratch.path, project_name + ".aedb") - local_scratch.copyfolder(example_folder, target_folder) - else: - target_folder = os.path.join(local_scratch.path, project_name + ".aedb") - else: - target_folder = os.path.join(local_scratch.path, generate_unique_name("TestEdb") + ".aedb") - return Edb( - target_folder, - edbversion=desktop_version, - ) - - return _method - - -@pytest.fixture(scope="function") -def lumped_design(): - """Fixture for creating a LumpedDesign object.""" - return LumpedDesign(config["desktopVersion"]) - - -@pytest.fixture(scope="function") -def distributed_design(): - """Fixture for creating a DistributedDesign object.""" - return DistributedDesign(config["desktopVersion"]) +apply_global_configuration(config) diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py deleted file mode 100644 index edae4f43d13..00000000000 --- a/tests/unit/conftest.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from ansys.aedt.core.generic.settings import settings - -settings.enable_error_handler = False diff --git a/tests/unit/extensions/conftest.py b/tests/unit/extensions/conftest.py index 73b759c7ea8..26b754393a4 100644 --- a/tests/unit/extensions/conftest.py +++ b/tests/unit/extensions/conftest.py @@ -22,9 +22,16 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from unittest.mock import MagicMock -from unittest.mock import PropertyMock -from unittest.mock import patch +""" +Unit Extensions Test Configuration +---------------------------------- + +This conftest.py contains configurations specific to unit extension tests. +It provides mock fixtures for testing extensions without requiring full +AEDT applications. General configurations are inherited from top-level. +""" + +from unittest.mock import MagicMock, PropertyMock, patch import pytest @@ -34,57 +41,71 @@ @pytest.fixture def mock_icepak_app(): """Fixture to mock Icepak application.""" - with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_aedt_application_property: - mock_aedt_application_instance = MagicMock() - mock_aedt_application_instance.design_type = "Icepak" - mock_aedt_application_property.return_value = mock_aedt_application_instance - - yield mock_aedt_application_instance + with patch.object( + ExtensionCommon, + "aedt_application", + new_callable=PropertyMock + ) as mock_property: + mock_instance = MagicMock() + mock_instance.design_type = "Icepak" + mock_property.return_value = mock_instance + yield mock_instance @pytest.fixture def mock_hfss_app(): """Fixture to mock HFSS application.""" - with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_aedt_application_property: - mock_aedt_application_instance = MagicMock() - mock_aedt_application_instance.design_type = "HFSS" - mock_aedt_application_property.return_value = mock_aedt_application_instance - - yield mock_aedt_application_instance + with patch.object( + ExtensionCommon, + "aedt_application", + new_callable=PropertyMock + ) as mock_property: + mock_instance = MagicMock() + mock_instance.design_type = "HFSS" + mock_property.return_value = mock_instance + yield mock_instance @pytest.fixture def mock_hfss_3d_layout_app(): - """Fixture to mock HFSS application.""" - with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_aedt_application_property: - mock_aedt_application_instance = MagicMock() - mock_aedt_application_instance.design_type = "HFSS 3D Layout Design" - mock_aedt_application_property.return_value = mock_aedt_application_instance - - yield mock_aedt_application_instance + """Fixture to mock HFSS 3D Layout application.""" + with patch.object( + ExtensionCommon, + "aedt_application", + new_callable=PropertyMock + ) as mock_property: + mock_instance = MagicMock() + mock_instance.design_type = "HFSS 3D Layout Design" + mock_property.return_value = mock_instance + yield mock_instance @pytest.fixture def mock_maxwell_3d_app(): """Fixture to mock Maxwell 3D application.""" - with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_aedt_application_property: - mock_aedt_application_instance = MagicMock() - mock_aedt_application_instance.design_type = "Maxwell 3D" - mock_aedt_application_property.return_value = mock_aedt_application_instance - - yield mock_aedt_application_instance + with patch.object( + ExtensionCommon, + "aedt_application", + new_callable=PropertyMock + ) as mock_property: + mock_instance = MagicMock() + mock_instance.design_type = "Maxwell 3D" + mock_property.return_value = mock_instance + yield mock_instance @pytest.fixture def mock_maxwell_2d_app(): - """Fixture to mock Maxwell 3D application.""" - with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_aedt_application_property: - mock_aedt_application_instance = MagicMock() - mock_aedt_application_instance.design_type = "Maxwell 2D" - mock_aedt_application_property.return_value = mock_aedt_application_instance - - yield mock_aedt_application_instance - + """Fixture to mock Maxwell 2D application.""" + with patch.object( + ExtensionCommon, + "aedt_application", + new_callable=PropertyMock + ) as mock_property: + mock_instance = MagicMock() + mock_instance.design_type = "Maxwell 2D" + mock_property.return_value = mock_instance + yield mock_instance @pytest.fixture def mock_circuit_app(): @@ -94,4 +115,4 @@ def mock_circuit_app(): mock_aedt_application_instance.design_type = "Circuit Design" mock_aedt_application_property.return_value = mock_aedt_application_instance - yield mock_aedt_application_instance + yield mock_aedt_application_instance \ No newline at end of file From 6d13be53265c7b51adeaca8144e993a90859f60e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 11:01:39 +0000 Subject: [PATCH 08/18] CHORE: Auto fixes from pre-commit hooks --- tests/conftest.py | 37 ++++++++--------------- tests/system/conftest.py | 4 +++ tests/system/emit/conftest.py | 21 ++----------- tests/system/extensions/conftest.py | 5 +-- tests/system/filter_solutions/conftest.py | 3 +- tests/system/general/conftest.py | 5 +-- tests/system/solvers/conftest.py | 4 ++- tests/system/visualization/conftest.py | 3 +- tests/unit/extensions/conftest.py | 37 ++++++----------------- 9 files changed, 39 insertions(+), 80 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 1d69983d2c8..c242019ec3b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -64,9 +64,7 @@ # Initialize default configuration - shared across all test types default_version = "2025.2" -os.environ[ - "ANSYSEM_FEATURE_SS544753_ICEPAK_VIRTUALMESHREGION_PARADIGM_ENABLE" -] = "1" +os.environ["ANSYSEM_FEATURE_SS544753_ICEPAK_VIRTUALMESHREGION_PARADIGM_ENABLE"] = "1" DEFAULT_CONFIG = { "desktopVersion": default_version, @@ -95,6 +93,7 @@ except Exception: # pragma: no cover pass + # Apply global configuration moved into a function for reuse and to support updates from nested conftest files def apply_global_configuration(cfg: dict): """Apply global configuration settings from a configuration dictionary. @@ -113,18 +112,13 @@ def apply_global_configuration(cfg: dict): settings.use_grpc_api = cfg.get("use_grpc", DEFAULT_CONFIG.get("use_grpc")) close_desktop = cfg.get("close_desktop", DEFAULT_CONFIG.get("close_desktop")) remove_lock = cfg.get("remove_lock", DEFAULT_CONFIG.get("remove_lock")) - settings.use_local_example_data = cfg.get( - "use_local_example_data", DEFAULT_CONFIG.get("use_local_example_data") - ) + settings.use_local_example_data = cfg.get("use_local_example_data", DEFAULT_CONFIG.get("use_local_example_data")) if settings.use_local_example_data: - settings.local_example_folder = cfg.get( - "local_example_folder", DEFAULT_CONFIG.get("local_example_folder") - ) + settings.local_example_folder = cfg.get("local_example_folder", DEFAULT_CONFIG.get("local_example_folder")) logger = pyaedt_logger - os.environ["PYAEDT_SCRIPT_VERSION"] = cfg.get( - "desktopVersion", DEFAULT_CONFIG.get("desktopVersion") - ) + os.environ["PYAEDT_SCRIPT_VERSION"] = cfg.get("desktopVersion", DEFAULT_CONFIG.get("desktopVersion")) + # Call the function to apply the current config values apply_global_configuration(config) @@ -132,6 +126,7 @@ def apply_global_configuration(cfg: dict): # Add current path to sys.path for imports sys.path.append(str(local_path)) + def generate_random_string(length): """Generate a random string of specified length.""" characters = string.ascii_letters + string.digits @@ -141,16 +136,11 @@ def generate_random_string(length): def generate_random_ident(): """Generate a random identifier for test folders.""" - ident = ( - "-" + generate_random_string(6) + "-" + - generate_random_string(6) + "-" + generate_random_string(6) - ) + ident = "-" + generate_random_string(6) + "-" + generate_random_string(6) + "-" + generate_random_string(6) return ident -def pytest_collection_modifyitems( - config: pytest.Config, items: List[pytest.Item] -): +def pytest_collection_modifyitems(config: pytest.Config, items: List[pytest.Item]): """Hook used to apply marker on tests.""" for item in items: # Mark unit, integration and system tests @@ -179,6 +169,7 @@ def pytest_collection_modifyitems( # SHARED FIXTURES # ================================ + @pytest.fixture(scope="session", autouse=True) def init_scratch(): """Initialize a global scratch directory for all tests.""" @@ -245,12 +236,8 @@ def patch_graphics_modules(monkeypatch): # Specific action to make a mock an attribute of another mock mocks["matplotlib"].pyplot = mocks["matplotlib.pyplot"] viz_interface = mocks["ansys.tools.visualization_interface"] - viz_backends = mocks[ - "ansys.tools.visualization_interface.backends" - ] + viz_backends = mocks["ansys.tools.visualization_interface.backends"] viz_interface.backends = viz_backends - viz_backends.pyvista = mocks[ - "ansys.tools.visualization_interface.backends.pyvista" - ] + viz_backends.pyvista = mocks["ansys.tools.visualization_interface.backends.pyvista"] yield mocks diff --git a/tests/system/conftest.py b/tests/system/conftest.py index 37616cd8293..c516f8de80e 100644 --- a/tests/system/conftest.py +++ b/tests/system/conftest.py @@ -50,6 +50,7 @@ def desktop(): except Exception: return False + @pytest.fixture(scope="module") def add_app(local_scratch): def _method( @@ -89,6 +90,7 @@ def _method( return _method + @pytest.fixture(scope="module") def test_project_file(local_scratch): def _method(project_name=None, subfolder=None): @@ -103,6 +105,7 @@ def _method(project_name=None, subfolder=None): return _method + @pytest.fixture(scope="module") def add_edb(local_scratch): def _method(project_name=None, subfolder=""): @@ -122,6 +125,7 @@ def _method(project_name=None, subfolder=""): return _method + @pytest.fixture(scope="function") def lumped_design(): """Fixture for creating a LumpedDesign object.""" diff --git a/tests/system/emit/conftest.py b/tests/system/emit/conftest.py index 387cb536171..7084c7c7eaa 100644 --- a/tests/system/emit/conftest.py +++ b/tests/system/emit/conftest.py @@ -41,28 +41,12 @@ """ -import gc import json -import os from pathlib import Path -import random -import shutil -import string import sys -import tempfile -import time -import pytest - -from ansys.aedt.core import Emit -from ansys.aedt.core.aedt_logger import pyaedt_logger -from ansys.aedt.core.desktop import Desktop -from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.desktop_sessions import ( - _desktop_sessions, -) -from ansys.aedt.core.internal.filesystem import Scratch -from tests.conftest import config, apply_global_configuration +from tests.conftest import apply_global_configuration +from tests.conftest import config local_path = Path(__file__).parent sys.path.append(str(local_path)) @@ -78,4 +62,3 @@ config.update(local_config) apply_global_configuration(config) - diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py index cdfb6dc9282..4cdba13fe08 100644 --- a/tests/system/extensions/conftest.py +++ b/tests/system/extensions/conftest.py @@ -45,7 +45,8 @@ import os import sys -from tests.conftest import apply_global_configuration, config +from tests.conftest import apply_global_configuration +from tests.conftest import config local_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(local_path) @@ -59,4 +60,4 @@ local_config = {} config.update(local_config) -apply_global_configuration(config) \ No newline at end of file +apply_global_configuration(config) diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py index 1714e306390..32bbca6d1f7 100644 --- a/tests/system/filter_solutions/conftest.py +++ b/tests/system/filter_solutions/conftest.py @@ -45,7 +45,8 @@ import os import sys -from tests.conftest import apply_global_configuration, config +from tests.conftest import apply_global_configuration +from tests.conftest import config local_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(local_path) diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index 74f858142bc..628ee682612 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -53,9 +53,7 @@ from ansys.aedt.core.aedt_logger import pyaedt_logger from ansys.aedt.core.desktop import Desktop from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.desktop_sessions import ( - _desktop_sessions, -) +from ansys.aedt.core.internal.desktop_sessions import _desktop_sessions from tests.conftest import apply_global_configuration from tests.conftest import config from tests.conftest import logger @@ -106,4 +104,3 @@ def desktop(): os.kill(pid, 9) except OSError: pass - diff --git a/tests/system/solvers/conftest.py b/tests/system/solvers/conftest.py index f463614ca66..44f8c98bd09 100644 --- a/tests/system/solvers/conftest.py +++ b/tests/system/solvers/conftest.py @@ -36,7 +36,9 @@ import json import os import sys -from tests.conftest import config, apply_global_configuration + +from tests.conftest import apply_global_configuration +from tests.conftest import config local_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(local_path) diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py index 6d27ec0a4f2..38cb2650e6d 100644 --- a/tests/system/visualization/conftest.py +++ b/tests/system/visualization/conftest.py @@ -45,7 +45,8 @@ import os import sys -from tests.conftest import config, apply_global_configuration +from tests.conftest import apply_global_configuration +from tests.conftest import config local_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(local_path) diff --git a/tests/unit/extensions/conftest.py b/tests/unit/extensions/conftest.py index 26b754393a4..7e99eb9093d 100644 --- a/tests/unit/extensions/conftest.py +++ b/tests/unit/extensions/conftest.py @@ -31,7 +31,9 @@ AEDT applications. General configurations are inherited from top-level. """ -from unittest.mock import MagicMock, PropertyMock, patch +from unittest.mock import MagicMock +from unittest.mock import PropertyMock +from unittest.mock import patch import pytest @@ -41,11 +43,7 @@ @pytest.fixture def mock_icepak_app(): """Fixture to mock Icepak application.""" - with patch.object( - ExtensionCommon, - "aedt_application", - new_callable=PropertyMock - ) as mock_property: + with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_property: mock_instance = MagicMock() mock_instance.design_type = "Icepak" mock_property.return_value = mock_instance @@ -55,11 +53,7 @@ def mock_icepak_app(): @pytest.fixture def mock_hfss_app(): """Fixture to mock HFSS application.""" - with patch.object( - ExtensionCommon, - "aedt_application", - new_callable=PropertyMock - ) as mock_property: + with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_property: mock_instance = MagicMock() mock_instance.design_type = "HFSS" mock_property.return_value = mock_instance @@ -69,11 +63,7 @@ def mock_hfss_app(): @pytest.fixture def mock_hfss_3d_layout_app(): """Fixture to mock HFSS 3D Layout application.""" - with patch.object( - ExtensionCommon, - "aedt_application", - new_callable=PropertyMock - ) as mock_property: + with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_property: mock_instance = MagicMock() mock_instance.design_type = "HFSS 3D Layout Design" mock_property.return_value = mock_instance @@ -83,11 +73,7 @@ def mock_hfss_3d_layout_app(): @pytest.fixture def mock_maxwell_3d_app(): """Fixture to mock Maxwell 3D application.""" - with patch.object( - ExtensionCommon, - "aedt_application", - new_callable=PropertyMock - ) as mock_property: + with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_property: mock_instance = MagicMock() mock_instance.design_type = "Maxwell 3D" mock_property.return_value = mock_instance @@ -97,16 +83,13 @@ def mock_maxwell_3d_app(): @pytest.fixture def mock_maxwell_2d_app(): """Fixture to mock Maxwell 2D application.""" - with patch.object( - ExtensionCommon, - "aedt_application", - new_callable=PropertyMock - ) as mock_property: + with patch.object(ExtensionCommon, "aedt_application", new_callable=PropertyMock) as mock_property: mock_instance = MagicMock() mock_instance.design_type = "Maxwell 2D" mock_property.return_value = mock_instance yield mock_instance + @pytest.fixture def mock_circuit_app(): """Fixture to mock Circuit application.""" @@ -115,4 +98,4 @@ def mock_circuit_app(): mock_aedt_application_instance.design_type = "Circuit Design" mock_aedt_application_property.return_value = mock_aedt_application_instance - yield mock_aedt_application_instance \ No newline at end of file + yield mock_aedt_application_instance From fa3eb44ae8295dad830b18bbf95a22ba60269cad Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Thu, 2 Oct 2025 13:03:08 +0200 Subject: [PATCH 09/18] Updated conftest docs AEDT version --- tests/system/emit/conftest.py | 2 +- tests/system/extensions/conftest.py | 2 +- tests/system/filter_solutions/conftest.py | 2 +- tests/system/general/conftest.py | 2 +- tests/system/visualization/conftest.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/system/emit/conftest.py b/tests/system/emit/conftest.py index 387cb536171..aca8135318c 100644 --- a/tests/system/emit/conftest.py +++ b/tests/system/emit/conftest.py @@ -34,7 +34,7 @@ The default configuration can be changed by placing a file called local_config.json in the same directory as this module. An example of the contents of local_config.json { - "desktopVersion": "2022.2", + "desktopVersion": "2025.2", "NonGraphical": false, "NewThread": false, } diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py index cdfb6dc9282..85a033b81db 100644 --- a/tests/system/extensions/conftest.py +++ b/tests/system/extensions/conftest.py @@ -34,7 +34,7 @@ The default configuration can be changed by placing a file called local_config.json in the same directory as this module. An example of the contents of local_config.json { - "desktopVersion": "2022.2", + "desktopVersion": "2025.2", "NonGraphical": false, "NewThread": false, } diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py index 1714e306390..2a1246f9e26 100644 --- a/tests/system/filter_solutions/conftest.py +++ b/tests/system/filter_solutions/conftest.py @@ -34,7 +34,7 @@ The default configuration can be changed by placing a file called local_config.json in the same directory as this module. An example of the contents of local_config.json { - "desktopVersion": "2022.2", + "desktopVersion": "2025.2", "NonGraphical": false, "NewThread": false, } diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index 74f858142bc..13bf8cd3a2b 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -34,7 +34,7 @@ The default configuration can be changed by placing a file called local_config.json in the same directory as this module. An example of the contents of local_config.json { - "desktopVersion": "2022.2", + "desktopVersion": "2025.2", "NonGraphical": false, "NewThread": false, } diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py index 6d27ec0a4f2..dfa0f108b83 100644 --- a/tests/system/visualization/conftest.py +++ b/tests/system/visualization/conftest.py @@ -34,7 +34,7 @@ The default configuration can be changed by placing a file called local_config.json in the same directory as this module. An example of the contents of local_config.json { - "desktopVersion": "2022.2", + "desktopVersion": "2025.2", "NonGraphical": false, "NewThread": false, } From d47ac497692eb8945e9e24e63be530abad7698a2 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Thu, 2 Oct 2025 11:05:11 +0000 Subject: [PATCH 10/18] chore: adding changelog file 6727.miscellaneous.md [dependabot-skip] --- doc/changelog.d/6727.miscellaneous.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/6727.miscellaneous.md diff --git a/doc/changelog.d/6727.miscellaneous.md b/doc/changelog.d/6727.miscellaneous.md new file mode 100644 index 00000000000..fa34ec7a98e --- /dev/null +++ b/doc/changelog.d/6727.miscellaneous.md @@ -0,0 +1 @@ +Outdated local config parameters From 58826acce8d406a98ae56b3337fdc202f47efda8 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Thu, 2 Oct 2025 11:08:13 +0000 Subject: [PATCH 11/18] chore: adding changelog file 6727.miscellaneous.md [dependabot-skip] --- doc/changelog.d/6727.miscellaneous.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changelog.d/6727.miscellaneous.md b/doc/changelog.d/6727.miscellaneous.md index fa34ec7a98e..21431d96fba 100644 --- a/doc/changelog.d/6727.miscellaneous.md +++ b/doc/changelog.d/6727.miscellaneous.md @@ -1 +1 @@ -Outdated local config parameters +Conftest refactoring and local_config cleaning From 6c8ea244882d6bfe9d38aae10c925f3a73b636ad Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Mon, 6 Oct 2025 12:09:29 +0200 Subject: [PATCH 12/18] Fixes --- .github/workflows/ci_cd.yml | 1 + .gitignore | 1 - tests/conftest.py | 82 +++++++------------ tests/pyaedt_settings.yaml | 18 ++++ tests/system/emit/conftest.py | 64 --------------- tests/system/extensions/conftest.py | 63 -------------- tests/system/extensions/test_cutout.py | 2 +- tests/system/extensions/test_export_layout.py | 2 +- .../extensions/test_fields_distribution.py | 2 +- .../system/extensions/test_parametrize_edb.py | 2 +- .../extensions/test_post_layout_design.py | 2 +- .../system/extensions/test_via_clustering.py | 2 +- tests/system/extensions/test_via_design.py | 2 +- tests/system/filter_solutions/conftest.py | 64 --------------- .../filter_solutions/test_desktop_types.py | 2 +- .../test_distributed_geometry.py | 2 +- .../test_distributed_parasitics.py | 2 +- .../test_distributed_radial.py | 2 +- .../test_distributed_substrate.py | 2 +- .../test_distributed_topology.py | 2 +- .../test_export_to_aedt.py | 2 +- .../test_optimization_goals_table.py | 2 +- .../test_filter/test_attributes.py | 2 +- .../test_filter/test_dll_interface.py | 2 +- .../test_filter/test_graph_setup.py | 2 +- .../test_filter/test_ideal_response.py | 2 +- .../test_filter/test_multiple_bands_table.py | 2 +- .../test_filter/test_transmission_zeros.py | 2 +- .../test_lumped_nodes_and_leads.py | 2 +- .../test_lumped_parasitics.py | 2 +- ...test_lumped_termination_impedance_table.py | 2 +- .../test_lumped_topology.py | 2 +- .../filter_solutions/test_raise_error.py | 2 +- tests/system/general/conftest.py | 21 +---- tests/system/solvers/conftest.py | 56 ------------- tests/system/visualization/conftest.py | 65 --------------- .../visualization/test_12_1_PostProcessing.py | 2 +- .../visualization/test_12_PostProcessing.py | 2 +- .../test_PostProcessing_Field_Report.py | 2 +- 39 files changed, 79 insertions(+), 414 deletions(-) create mode 100644 tests/pyaedt_settings.yaml delete mode 100644 tests/system/emit/conftest.py delete mode 100644 tests/system/extensions/conftest.py delete mode 100644 tests/system/filter_solutions/conftest.py delete mode 100644 tests/system/solvers/conftest.py delete mode 100644 tests/system/visualization/conftest.py diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 822e191b7f6..6ad8b1026fb 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -18,6 +18,7 @@ env: DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com' ON_CI: True PYTEST_ARGUMENTS: '-vvv --color=yes -ra --durations=25 --maxfail=10 --cov=ansys.aedt.core --cov-report=html --cov-report=xml --junitxml=junit/test-results.xml' + PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.gitignore b/.gitignore index ba1713f0fb5..caf3b538220 100644 --- a/.gitignore +++ b/.gitignore @@ -400,7 +400,6 @@ model.index\+ # test coverage output /.cov/ -/tests/system/general/pyaedt_settings.yaml # Custom instructions for GitHub Copilot .github/copilot-instructions.md diff --git a/tests/conftest.py b/tests/conftest.py index c242019ec3b..9eb1b99cd3c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -50,34 +50,21 @@ FILTER_SOLUTIONS_TEST_PREFIX = "tests/system/filter_solutions" EMIT_TEST_PREFIX = "tests/system/emit" -# Global settings configuration - applied to all tests -settings.enable_local_log_file = False -settings.enable_global_log_file = False -settings.number_of_grpc_api_retries = 6 -settings.retry_n_times_time_interval = 0.5 -settings.enable_error_handler = False -settings.enable_desktop_logs = False -settings.desktop_launch_timeout = 180 -settings.release_on_exception = False -settings.wait_for_license = True -settings.enable_pandas_output = True - # Initialize default configuration - shared across all test types -default_version = "2025.2" os.environ["ANSYSEM_FEATURE_SS544753_ICEPAK_VIRTUALMESHREGION_PARADIGM_ENABLE"] = "1" DEFAULT_CONFIG = { - "desktopVersion": default_version, + "desktopVersion": "2025.2", "NonGraphical": True, "NewThread": True, - "skip_circuits": False, - "skip_modelithics": True, "use_grpc": True, - "disable_sat_bounding_box": True, "close_desktop": True, "remove_lock": False, - "local_example_folder": None, + "disable_sat_bounding_box": True, "use_local_example_data": False, + "local_example_folder": None, + "skip_circuits": False, + "skip_modelithics": True, } # Load top-level configuration @@ -93,35 +80,22 @@ except Exception: # pragma: no cover pass +desktop_version = config.get("desktopVersion", DEFAULT_CONFIG.get("desktopVersion")) +NONGRAPHICAL = config.get("NonGraphical", DEFAULT_CONFIG.get("NonGraphical")) +new_thread = config.get("NewThread", DEFAULT_CONFIG.get("NewThread")) +settings.use_grpc_api = config.get("use_grpc", DEFAULT_CONFIG.get("use_grpc")) +close_desktop = config.get("close_desktop", DEFAULT_CONFIG.get("close_desktop")) +remove_lock = config.get("remove_lock", DEFAULT_CONFIG.get("remove_lock")) +settings.disable_bounding_box_sat = config.get( + "disable_sat_bounding_box", DEFAULT_CONFIG.get("disable_sat_bounding_box") +) +settings.use_local_example_data = config.get("use_local_example_data", DEFAULT_CONFIG.get("use_local_example_data")) +if settings.use_local_example_data: + settings.local_example_folder = config.get("local_example_folder", DEFAULT_CONFIG.get("local_example_folder")) -# Apply global configuration moved into a function for reuse and to support updates from nested conftest files -def apply_global_configuration(cfg: dict): - """Apply global configuration settings from a configuration dictionary. - - This updates module-level variables, the shared `settings` object and environment - variables. Defaults are taken from DEFAULT_CONFIG when keys are missing. - """ - global NONGRAPHICAL, desktop_version, new_thread, close_desktop, remove_lock, logger - - NONGRAPHICAL = cfg.get("NonGraphical", DEFAULT_CONFIG.get("NonGraphical")) - settings.disable_bounding_box_sat = cfg.get( - "disable_sat_bounding_box", DEFAULT_CONFIG.get("disable_sat_bounding_box") - ) - desktop_version = cfg.get("desktopVersion", DEFAULT_CONFIG.get("desktopVersion")) - new_thread = cfg.get("NewThread", DEFAULT_CONFIG.get("NewThread")) - settings.use_grpc_api = cfg.get("use_grpc", DEFAULT_CONFIG.get("use_grpc")) - close_desktop = cfg.get("close_desktop", DEFAULT_CONFIG.get("close_desktop")) - remove_lock = cfg.get("remove_lock", DEFAULT_CONFIG.get("remove_lock")) - settings.use_local_example_data = cfg.get("use_local_example_data", DEFAULT_CONFIG.get("use_local_example_data")) - if settings.use_local_example_data: - settings.local_example_folder = cfg.get("local_example_folder", DEFAULT_CONFIG.get("local_example_folder")) - - logger = pyaedt_logger - os.environ["PYAEDT_SCRIPT_VERSION"] = cfg.get("desktopVersion", DEFAULT_CONFIG.get("desktopVersion")) - +logger = pyaedt_logger +os.environ["PYAEDT_SCRIPT_VERSION"] = config.get("desktopVersion", DEFAULT_CONFIG.get("desktopVersion")) -# Call the function to apply the current config values -apply_global_configuration(config) # Add current path to sys.path for imports sys.path.append(str(local_path)) @@ -144,24 +118,24 @@ def pytest_collection_modifyitems(config: pytest.Config, items: List[pytest.Item """Hook used to apply marker on tests.""" for item in items: # Mark unit, integration and system tests - if item.nodeid.startswith(UNIT_TEST_PREFIX): + if item.nodeid.startswith("UNIT_TEST_PREFIX"): item.add_marker(pytest.mark.unit) - elif item.nodeid.startswith(INTEGRATION_TEST_PREFIX): + elif item.nodeid.startswith("INTEGRATION_TEST_PREFIX"): item.add_marker(pytest.mark.integration) - elif item.nodeid.startswith(SYSTEM_TEST_PREFIX): + elif item.nodeid.startswith("SYSTEM_TEST_PREFIX"): item.add_marker(pytest.mark.system) # Finer markers for system tests - if item.nodeid.startswith(SYSTEM_SOLVERS_TEST_PREFIX): + if item.nodeid.startswith("SYSTEM_SOLVERS_TEST_PREFIX"): item.add_marker(pytest.mark.solvers) - elif item.nodeid.startswith(SYSTEM_GENERAL_TEST_PREFIX): + elif item.nodeid.startswith("SYSTEM_GENERAL_TEST_PREFIX"): item.add_marker(pytest.mark.general) - elif item.nodeid.startswith(VISUALIZATION_GENERAL_TEST_PREFIX): + elif item.nodeid.startswith("VISUALIZATION_GENERAL_TEST_PREFIX"): item.add_marker(pytest.mark.visualization) - elif item.nodeid.startswith(EXTENSIONS_GENERAL_TEST_PREFIX): + elif item.nodeid.startswith("EXTENSIONS_GENERAL_TEST_PREFIX"): item.add_marker(pytest.mark.extensions) - elif item.nodeid.startswith(FILTER_SOLUTIONS_TEST_PREFIX): + elif item.nodeid.startswith("FILTER_SOLUTIONS_TEST_PREFIX"): item.add_marker(pytest.mark.filter_solutions) - elif item.nodeid.startswith(EMIT_TEST_PREFIX): + elif item.nodeid.startswith("EMIT_TEST_PREFIX"): item.add_marker(pytest.mark.emit) diff --git a/tests/pyaedt_settings.yaml b/tests/pyaedt_settings.yaml new file mode 100644 index 00000000000..d508b3655e2 --- /dev/null +++ b/tests/pyaedt_settings.yaml @@ -0,0 +1,18 @@ +# PyAEDT settings configuration for test environment +# This file configures PyAEDT settings for all tests + +log: + enable_local_log_file: false + enable_global_log_file: false + enable_desktop_logs: false + +general: + number_of_grpc_api_retries: 6 + retry_n_times_time_interval: 0.5 + enable_error_handler: false + desktop_launch_timeout: 180 + release_on_exception: false + wait_for_license: true + enable_pandas_output: true +lsf: {} + # LSF settings are kept at defaults for test environment diff --git a/tests/system/emit/conftest.py b/tests/system/emit/conftest.py deleted file mode 100644 index 6f4136e1cd4..00000000000 --- a/tests/system/emit/conftest.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -""" -Unit Test Configuration Module -------------------------------- - -Description -=========== - -This module contains the configuration and fixture for the pytest-based unit tests for PyAEDT. - -The default configuration can be changed by placing a file called local_config.json in the same -directory as this module. An example of the contents of local_config.json -{ - "desktopVersion": "2025.2", - "NonGraphical": false, - "NewThread": false, -} - -""" - -import json -from pathlib import Path -import sys - -from tests.conftest import apply_global_configuration -from tests.conftest import config - -local_path = Path(__file__).parent -sys.path.append(str(local_path)) - -# Check for the local config file, override defaults if found -local_config_file = Path(local_path) / "local_config.json" -if local_config_file.exists(): - try: - with open(local_config_file) as f: - local_config = json.load(f) - except Exception: # pragma: no cover - local_config = {} - config.update(local_config) - -apply_global_configuration(config) diff --git a/tests/system/extensions/conftest.py b/tests/system/extensions/conftest.py deleted file mode 100644 index 0280b8f99ca..00000000000 --- a/tests/system/extensions/conftest.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -""" -Unit Test Configuration Module -------------------------------- - -Description -=========== - -This module contains the configuration and fixture for the pytest-based unit tests for PyAEDT. - -The default configuration can be changed by placing a file called local_config.json in the same -directory as this module. An example of the contents of local_config.json -{ - "desktopVersion": "2025.2", - "NonGraphical": false, - "NewThread": false, -} - -""" - -import json -import os -import sys - -from tests.conftest import apply_global_configuration -from tests.conftest import config - -local_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(local_path) -# Check for the local config file, override defaults if found -local_config_file = os.path.join(local_path, "local_config.json") -if os.path.exists(local_config_file): - try: - with open(local_config_file) as f: - local_config = json.load(f) - except Exception: # pragma: no cover - local_config = {} - config.update(local_config) - -apply_global_configuration(config) diff --git a/tests/system/extensions/test_cutout.py b/tests/system/extensions/test_cutout.py index bc550312fcb..75681b6ebd9 100644 --- a/tests/system/extensions/test_cutout.py +++ b/tests/system/extensions/test_cutout.py @@ -32,7 +32,7 @@ from ansys.aedt.core.extensions.hfss3dlayout.cutout import CutoutData from ansys.aedt.core.extensions.hfss3dlayout.cutout import main from ansys.aedt.core.hfss3dlayout import Hfss3dLayout -from tests.system.extensions.conftest import config +from tests.conftest import config AEDB_FILE_NAME = "ANSYS-HSD_V1" TEST_SUBFOLDER = "T45" diff --git a/tests/system/extensions/test_export_layout.py b/tests/system/extensions/test_export_layout.py index f8963e9cd68..cdf86369d3f 100644 --- a/tests/system/extensions/test_export_layout.py +++ b/tests/system/extensions/test_export_layout.py @@ -29,7 +29,7 @@ from ansys.aedt.core.extensions.hfss3dlayout.export_layout import ExportLayoutExtensionData from ansys.aedt.core.extensions.hfss3dlayout.export_layout import main from ansys.aedt.core.hfss3dlayout import Hfss3dLayout -from tests.system.extensions.conftest import config +from tests.conftest import config AEDB_FILE_NAME = "ANSYS-HSD_V1" TEST_SUBFOLDER = "T45" diff --git a/tests/system/extensions/test_fields_distribution.py b/tests/system/extensions/test_fields_distribution.py index d43124b522d..67ccaaa91ca 100644 --- a/tests/system/extensions/test_fields_distribution.py +++ b/tests/system/extensions/test_fields_distribution.py @@ -28,7 +28,7 @@ import pytest import ansys.aedt.core -from tests.system.extensions.conftest import local_path as extensions_local_path +from tests.conftest import local_path as extensions_local_path # Test project constants fields_distribution_project = "transformer_loss_distribution" diff --git a/tests/system/extensions/test_parametrize_edb.py b/tests/system/extensions/test_parametrize_edb.py index c8a9779b0ec..749790b586e 100644 --- a/tests/system/extensions/test_parametrize_edb.py +++ b/tests/system/extensions/test_parametrize_edb.py @@ -32,7 +32,7 @@ from ansys.aedt.core.extensions.hfss3dlayout.parametrize_edb import main from ansys.aedt.core.generic.settings import is_linux from ansys.aedt.core.internal.errors import AEDTRuntimeError -from tests.system.extensions.conftest import local_path as extensions_local_path +from tests.conftest import local_path as extensions_local_path pytest.importorskip("pyedb", "0.21.0") diff --git a/tests/system/extensions/test_post_layout_design.py b/tests/system/extensions/test_post_layout_design.py index 00ab04192b8..78b78c65c66 100644 --- a/tests/system/extensions/test_post_layout_design.py +++ b/tests/system/extensions/test_post_layout_design.py @@ -30,7 +30,7 @@ from ansys.aedt.core.extensions.hfss3dlayout import post_layout_design from ansys.aedt.core.extensions.hfss3dlayout.post_layout_design import PostLayoutDesignExtensionData from ansys.aedt.core.internal.errors import AEDTRuntimeError -from tests.system.extensions.conftest import local_path as extensions_local_path +from tests.conftest import local_path as extensions_local_path # Get local path for test files local_path = os.path.dirname(os.path.realpath(__file__)) diff --git a/tests/system/extensions/test_via_clustering.py b/tests/system/extensions/test_via_clustering.py index 060ff1cb4f2..4cfaaecfb5d 100644 --- a/tests/system/extensions/test_via_clustering.py +++ b/tests/system/extensions/test_via_clustering.py @@ -32,7 +32,7 @@ from ansys.aedt.core.extensions.hfss3dlayout.via_clustering import main from ansys.aedt.core.generic.settings import is_linux from ansys.aedt.core.internal.errors import AEDTRuntimeError -from tests.system.extensions.conftest import local_path as extensions_local_path +from tests.conftest import local_path as extensions_local_path def test_via_clustering_main_function(local_scratch): diff --git a/tests/system/extensions/test_via_design.py b/tests/system/extensions/test_via_design.py index db9609700a9..ae5a679d903 100644 --- a/tests/system/extensions/test_via_design.py +++ b/tests/system/extensions/test_via_design.py @@ -30,7 +30,7 @@ from ansys.aedt.core.extensions.hfss3dlayout.via_design import EXPORT_EXAMPLES from ansys.aedt.core.extensions.hfss3dlayout.via_design import ViaDesignExtension from ansys.aedt.core.generic.settings import is_linux -from tests.system.extensions.conftest import config +from tests.conftest import config @pytest.mark.skipif( diff --git a/tests/system/filter_solutions/conftest.py b/tests/system/filter_solutions/conftest.py deleted file mode 100644 index 03838e63764..00000000000 --- a/tests/system/filter_solutions/conftest.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -""" -Unit Test Configuration Module -------------------------------- - -Description -=========== - -This module contains the configuration and fixture for the pytest-based unit tests for PyAEDT. - -The default configuration can be changed by placing a file called local_config.json in the same -directory as this module. An example of the contents of local_config.json -{ - "desktopVersion": "2025.2", - "NonGraphical": false, - "NewThread": false, -} - -""" - -import json -import os -import sys - -from tests.conftest import apply_global_configuration -from tests.conftest import config - -local_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(local_path) - -# Check for the local config file, override defaults if found -local_config_file = os.path.join(local_path, "local_config.json") -if os.path.exists(local_config_file): - try: - with open(local_config_file) as f: - local_config = json.load(f) - except Exception: # pragma: no cover - local_config = {} - config.update(local_config) - -apply_global_configuration(config) diff --git a/tests/system/filter_solutions/test_desktop_types.py b/tests/system/filter_solutions/test_desktop_types.py index 0b09ff6879f..0383c8c95c2 100644 --- a/tests/system/filter_solutions/test_desktop_types.py +++ b/tests/system/filter_solutions/test_desktop_types.py @@ -28,7 +28,7 @@ from ansys.aedt.core import Hfss from ansys.aedt.core import Hfss3dLayout from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config @pytest.mark.skipif(is_linux, reason="FilterSolutions API is not supported on Linux.") diff --git a/tests/system/filter_solutions/test_distributed_filter/test_distributed_geometry.py b/tests/system/filter_solutions/test_distributed_filter/test_distributed_geometry.py index dc407d81e28..41236931185 100644 --- a/tests/system/filter_solutions/test_distributed_filter/test_distributed_geometry.py +++ b/tests/system/filter_solutions/test_distributed_filter/test_distributed_geometry.py @@ -25,7 +25,7 @@ import pytest from ansys.aedt.core.generic.general_methods import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config @pytest.mark.skipif(is_linux, reason="FilterSolutions API is not applicable on Linux.") diff --git a/tests/system/filter_solutions/test_distributed_filter/test_distributed_parasitics.py b/tests/system/filter_solutions/test_distributed_filter/test_distributed_parasitics.py index ad7032749ca..1cdea17ce51 100644 --- a/tests/system/filter_solutions/test_distributed_filter/test_distributed_parasitics.py +++ b/tests/system/filter_solutions/test_distributed_filter/test_distributed_parasitics.py @@ -26,7 +26,7 @@ from ansys.aedt.core.filtersolutions_core.distributed_topology import TopologyType from ansys.aedt.core.generic.general_methods import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.resources import read_resource_file diff --git a/tests/system/filter_solutions/test_distributed_filter/test_distributed_radial.py b/tests/system/filter_solutions/test_distributed_filter/test_distributed_radial.py index a473539fd62..b0f6dcbf380 100644 --- a/tests/system/filter_solutions/test_distributed_filter/test_distributed_radial.py +++ b/tests/system/filter_solutions/test_distributed_filter/test_distributed_radial.py @@ -25,7 +25,7 @@ import pytest from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config @pytest.mark.skipif(is_linux, reason="FilterSolutions API is not applicable on Linux.") diff --git a/tests/system/filter_solutions/test_distributed_filter/test_distributed_substrate.py b/tests/system/filter_solutions/test_distributed_filter/test_distributed_substrate.py index 9d249913a36..d5c0cb0a2bf 100644 --- a/tests/system/filter_solutions/test_distributed_filter/test_distributed_substrate.py +++ b/tests/system/filter_solutions/test_distributed_filter/test_distributed_substrate.py @@ -28,7 +28,7 @@ from ansys.aedt.core.filtersolutions_core.export_to_aedt import SubstrateResistivity from ansys.aedt.core.filtersolutions_core.export_to_aedt import SubstrateType from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config @pytest.mark.skipif(is_linux, reason="FilterSolutions API is not supported on Linux.") diff --git a/tests/system/filter_solutions/test_distributed_filter/test_distributed_topology.py b/tests/system/filter_solutions/test_distributed_filter/test_distributed_topology.py index af60af7b43d..77fb5a91732 100644 --- a/tests/system/filter_solutions/test_distributed_filter/test_distributed_topology.py +++ b/tests/system/filter_solutions/test_distributed_filter/test_distributed_topology.py @@ -29,7 +29,7 @@ from ansys.aedt.core.filtersolutions_core.distributed_topology import TapPosition from ansys.aedt.core.filtersolutions_core.distributed_topology import TopologyType from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.resources import read_resource_file diff --git a/tests/system/filter_solutions/test_export_to_aedt/test_export_to_aedt.py b/tests/system/filter_solutions/test_export_to_aedt/test_export_to_aedt.py index 8edaa24bc0e..25904d3477f 100644 --- a/tests/system/filter_solutions/test_export_to_aedt/test_export_to_aedt.py +++ b/tests/system/filter_solutions/test_export_to_aedt/test_export_to_aedt.py @@ -33,7 +33,7 @@ from ansys.aedt.core.filtersolutions_core.export_to_aedt import SubstrateResistivity from ansys.aedt.core.filtersolutions_core.export_to_aedt import SubstrateType from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.resources import read_resource_file from tests.system.filter_solutions.resources import resource_path diff --git a/tests/system/filter_solutions/test_export_to_aedt/test_optimization_goals_table.py b/tests/system/filter_solutions/test_export_to_aedt/test_optimization_goals_table.py index 9a77ec4de5f..cd76a4d4f27 100644 --- a/tests/system/filter_solutions/test_export_to_aedt/test_optimization_goals_table.py +++ b/tests/system/filter_solutions/test_export_to_aedt/test_optimization_goals_table.py @@ -27,7 +27,7 @@ from ansys.aedt.core.filtersolutions_core.optimization_goals_table import OptimizationGoalParameter from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.resources import resource_path diff --git a/tests/system/filter_solutions/test_filter/test_attributes.py b/tests/system/filter_solutions/test_filter/test_attributes.py index 0dd71f15071..66a591f6fc0 100644 --- a/tests/system/filter_solutions/test_filter/test_attributes.py +++ b/tests/system/filter_solutions/test_filter/test_attributes.py @@ -37,7 +37,7 @@ from ansys.aedt.core.filtersolutions_core.attributes import SinglePointRippleInfZeros from ansys.aedt.core.filtersolutions_core.attributes import StopbandDefinition from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config default_center_freq = "1G" changed_freq = "500M" diff --git a/tests/system/filter_solutions/test_filter/test_dll_interface.py b/tests/system/filter_solutions/test_filter/test_dll_interface.py index 09911f62629..6f7bdf7b753 100644 --- a/tests/system/filter_solutions/test_filter/test_dll_interface.py +++ b/tests/system/filter_solutions/test_filter/test_dll_interface.py @@ -31,7 +31,7 @@ import ansys.aedt.core.filtersolutions_core from ansys.aedt.core.filtersolutions_core.attributes import FilterType from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.test_filter import test_transmission_zeros diff --git a/tests/system/filter_solutions/test_filter/test_graph_setup.py b/tests/system/filter_solutions/test_filter/test_graph_setup.py index d279f5dbd90..b8ee89eae2c 100644 --- a/tests/system/filter_solutions/test_filter/test_graph_setup.py +++ b/tests/system/filter_solutions/test_filter/test_graph_setup.py @@ -25,7 +25,7 @@ import pytest from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config @pytest.mark.skipif(is_linux, reason="FilterSolutions API is not supported on Linux.") diff --git a/tests/system/filter_solutions/test_filter/test_ideal_response.py b/tests/system/filter_solutions/test_filter/test_ideal_response.py index cc507bd0910..172910851ed 100644 --- a/tests/system/filter_solutions/test_filter/test_ideal_response.py +++ b/tests/system/filter_solutions/test_filter/test_ideal_response.py @@ -30,7 +30,7 @@ from ansys.aedt.core.filtersolutions_core.ideal_response import SParametersResponseColumn from ansys.aedt.core.filtersolutions_core.ideal_response import TimeResponseColumn from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.resources import read_resource_file diff --git a/tests/system/filter_solutions/test_filter/test_multiple_bands_table.py b/tests/system/filter_solutions/test_filter/test_multiple_bands_table.py index 3c20a680f27..caf371601bd 100644 --- a/tests/system/filter_solutions/test_filter/test_multiple_bands_table.py +++ b/tests/system/filter_solutions/test_filter/test_multiple_bands_table.py @@ -25,7 +25,7 @@ import pytest from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config @pytest.mark.skipif(is_linux, reason="FilterSolutions API is not supported on Linux.") diff --git a/tests/system/filter_solutions/test_filter/test_transmission_zeros.py b/tests/system/filter_solutions/test_filter/test_transmission_zeros.py index abc734cc25b..7758f37fdd0 100644 --- a/tests/system/filter_solutions/test_filter/test_transmission_zeros.py +++ b/tests/system/filter_solutions/test_filter/test_transmission_zeros.py @@ -25,7 +25,7 @@ import pytest from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config @pytest.mark.skipif(is_linux, reason="FilterSolutions API is not supported on Linux.") diff --git a/tests/system/filter_solutions/test_lumped_filter/test_lumped_nodes_and_leads.py b/tests/system/filter_solutions/test_lumped_filter/test_lumped_nodes_and_leads.py index 9b5c26344c4..ba6fd6547d9 100644 --- a/tests/system/filter_solutions/test_lumped_filter/test_lumped_nodes_and_leads.py +++ b/tests/system/filter_solutions/test_lumped_filter/test_lumped_nodes_and_leads.py @@ -25,7 +25,7 @@ import pytest from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.resources import read_resource_file diff --git a/tests/system/filter_solutions/test_lumped_filter/test_lumped_parasitics.py b/tests/system/filter_solutions/test_lumped_filter/test_lumped_parasitics.py index 6cb0e55a84d..cce59769e39 100644 --- a/tests/system/filter_solutions/test_lumped_filter/test_lumped_parasitics.py +++ b/tests/system/filter_solutions/test_lumped_filter/test_lumped_parasitics.py @@ -25,7 +25,7 @@ import pytest from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.resources import read_resource_file diff --git a/tests/system/filter_solutions/test_lumped_filter/test_lumped_termination_impedance_table.py b/tests/system/filter_solutions/test_lumped_filter/test_lumped_termination_impedance_table.py index a7ddb7b1eb6..a6c95424b57 100644 --- a/tests/system/filter_solutions/test_lumped_filter/test_lumped_termination_impedance_table.py +++ b/tests/system/filter_solutions/test_lumped_filter/test_lumped_termination_impedance_table.py @@ -27,7 +27,7 @@ from ansys.aedt.core.filtersolutions_core.lumped_termination_impedance_table import ComplexReactanceType from ansys.aedt.core.filtersolutions_core.lumped_termination_impedance_table import ComplexTerminationDefinition from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config @pytest.mark.skipif(is_linux, reason="FilterSolutions API is not supported on Linux.") diff --git a/tests/system/filter_solutions/test_lumped_filter/test_lumped_topology.py b/tests/system/filter_solutions/test_lumped_filter/test_lumped_topology.py index 083b50eab3a..bb1b8c1eb33 100644 --- a/tests/system/filter_solutions/test_lumped_filter/test_lumped_topology.py +++ b/tests/system/filter_solutions/test_lumped_filter/test_lumped_topology.py @@ -28,7 +28,7 @@ from ansys.aedt.core.filtersolutions_core.attributes import FilterClass from ansys.aedt.core.filtersolutions_core.attributes import FilterType from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.resources import read_resource_file diff --git a/tests/system/filter_solutions/test_raise_error.py b/tests/system/filter_solutions/test_raise_error.py index e72df3b381e..38082399ffc 100644 --- a/tests/system/filter_solutions/test_raise_error.py +++ b/tests/system/filter_solutions/test_raise_error.py @@ -25,7 +25,7 @@ import pytest from ansys.aedt.core.generic.settings import is_linux -from tests.system.filter_solutions.conftest import config +from tests.conftest import config from tests.system.filter_solutions.test_filter import test_transmission_zeros diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index 6156aa5093b..0830fce05c5 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -42,7 +42,6 @@ """ import gc -import json import os import sys import tempfile @@ -53,26 +52,12 @@ from ansys.aedt.core.aedt_logger import pyaedt_logger from ansys.aedt.core.desktop import Desktop from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.desktop_sessions import _desktop_sessions -from tests.conftest import apply_global_configuration +from ansys.aedt.core.internal.desktop_sessions import ( + _desktop_sessions, +) from tests.conftest import config from tests.conftest import logger -local_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(local_path) - -# Check for the local config file, override defaults if found -local_config_file = os.path.join(local_path, "local_config.json") -if os.path.exists(local_config_file): - try: - with open(local_config_file) as f: - local_config = json.load(f) - except Exception: # pragma: no cover - local_config = {} - config.update(local_config) - -apply_global_configuration(config) - def _delete_objects(): settings.remote_api = False diff --git a/tests/system/solvers/conftest.py b/tests/system/solvers/conftest.py deleted file mode 100644 index 44f8c98bd09..00000000000 --- a/tests/system/solvers/conftest.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -""" -System Solvers Test Configuration ---------------------------------- - -This conftest.py contains configurations specific to system solver tests. -It extends the top-level tests/conftest.py with solver-specific fixtures. - -Local configurations can override defaults by creating a local_config.json -file in this directory with solver-specific parameters only. -""" - -import json -import os -import sys - -from tests.conftest import apply_global_configuration -from tests.conftest import config - -local_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(local_path) - -# Check for the local config file, override defaults if found -local_config_file = os.path.join(local_path, "local_config.json") -if os.path.exists(local_config_file): - try: - with open(local_config_file) as f: - local_config = json.load(f) - except Exception: # pragma: no cover - local_config = {} - config.update(local_config) - -apply_global_configuration(config) diff --git a/tests/system/visualization/conftest.py b/tests/system/visualization/conftest.py deleted file mode 100644 index bbb00c10b1b..00000000000 --- a/tests/system/visualization/conftest.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. -# SPDX-License-Identifier: MIT -# -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -""" -Unit Test Configuration Module -------------------------------- - -Description -=========== - -This module contains the configuration and fixture for the pytest-based unit tests for PyAEDT. - -The default configuration can be changed by placing a file called local_config.json in the same -directory as this module. An example of the contents of local_config.json -{ - "desktopVersion": "2025.2", - "NonGraphical": false, - "NewThread": false, -} - -""" - -import json -import os -import sys - -from tests.conftest import apply_global_configuration -from tests.conftest import config - -local_path = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(local_path) - - -# Check for the local config file, override defaults if found -local_config_file = os.path.join(local_path, "local_config.json") -if os.path.exists(local_config_file): - try: - with open(local_config_file) as f: - local_config = json.load(f) - except Exception: # pragma: no cover - local_config = {} - config.update(local_config) - -apply_global_configuration(config) diff --git a/tests/system/visualization/test_12_1_PostProcessing.py b/tests/system/visualization/test_12_1_PostProcessing.py index 7453cd5ce65..447ad39dd30 100644 --- a/tests/system/visualization/test_12_1_PostProcessing.py +++ b/tests/system/visualization/test_12_1_PostProcessing.py @@ -37,7 +37,7 @@ from ansys.aedt.core.visualization.plot.pyvista import ModelPlotter from ansys.aedt.core.visualization.plot.pyvista import _parse_aedtplt from tests import TESTS_VISUALIZATION_PATH -from tests.system.visualization.conftest import config +from tests.conftest import config test_project_name = "coax_setup_solved_231" m2d_trace_export_table = "m2d" diff --git a/tests/system/visualization/test_12_PostProcessing.py b/tests/system/visualization/test_12_PostProcessing.py index cec8c7c3ca1..3f8fd801b85 100644 --- a/tests/system/visualization/test_12_PostProcessing.py +++ b/tests/system/visualization/test_12_PostProcessing.py @@ -39,7 +39,7 @@ from ansys.aedt.core.visualization.plot.pyvista import _parse_aedtplt from ansys.aedt.core.visualization.plot.pyvista import _parse_streamline from tests import TESTS_VISUALIZATION_PATH -from tests.system.visualization.conftest import config +from tests.conftest import config test_field_name = "Potter_Horn_242" q3d_file = "via_gsg_solved" diff --git a/tests/system/visualization/test_PostProcessing_Field_Report.py b/tests/system/visualization/test_PostProcessing_Field_Report.py index f11df096e6b..b1a97a94d50 100644 --- a/tests/system/visualization/test_PostProcessing_Field_Report.py +++ b/tests/system/visualization/test_PostProcessing_Field_Report.py @@ -164,7 +164,7 @@ def test_reports_by_category_far_antenna_parameters_2(self, h3d_potter_horn): def test_create_report_from_configuration_template(self, h3d_potter_horn): from tests import TESTS_VISUALIZATION_PATH - from tests.system.visualization.conftest import config + from tests.conftest import config new_report4 = h3d_potter_horn.post.reports_by_category.antenna_parameters( "db(PeakRealizedGain)", infinite_sphere="3D" From 686b6e14834b721b6a33223e20a3ef9d82fd452e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 10:10:22 +0000 Subject: [PATCH 13/18] CHORE: Auto fixes from pre-commit hooks --- tests/system/general/conftest.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/system/general/conftest.py b/tests/system/general/conftest.py index 0830fce05c5..daa9a8bf8e1 100644 --- a/tests/system/general/conftest.py +++ b/tests/system/general/conftest.py @@ -52,9 +52,7 @@ from ansys.aedt.core.aedt_logger import pyaedt_logger from ansys.aedt.core.desktop import Desktop from ansys.aedt.core.generic.settings import settings -from ansys.aedt.core.internal.desktop_sessions import ( - _desktop_sessions, -) +from ansys.aedt.core.internal.desktop_sessions import _desktop_sessions from tests.conftest import config from tests.conftest import logger From 135d0c98a781e6d8d57817686dae9169662ddd03 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Mon, 6 Oct 2025 12:41:42 +0200 Subject: [PATCH 14/18] Fixes --- .github/workflows/ci_cd.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 6ad8b1026fb..d45bfef89f1 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -18,7 +18,6 @@ env: DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com' ON_CI: True PYTEST_ARGUMENTS: '-vvv --color=yes -ra --durations=25 --maxfail=10 --cov=ansys.aedt.core --cov-report=html --cov-report=xml --junitxml=junit/test-results.xml' - PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -268,6 +267,7 @@ jobs: - name: Run tests marked with 'solvers' env: PYTHONMALLOC: malloc + PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml' run: | .venv\Scripts\Activate.ps1 pytest ${{ env.PYTEST_ARGUMENTS }} --timeout=600 -m solvers @@ -332,6 +332,7 @@ jobs: - name: Run tests marked with 'solvers' run: | export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT252 }}/common/mono/Linux64/lib64:$LD_LIBRARY_PATH + export PYAEDT_LOCAL_SETTINGS_PATH='tests/pyaedt_settings.yaml' source .venv/bin/activate pytest ${{ env.PYTEST_ARGUMENTS }} --timeout=600 -m solvers @@ -400,6 +401,7 @@ jobs: uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2 env: PYTHONMALLOC: malloc + PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml' with: max_attempts: 2 retry_on: error @@ -480,6 +482,7 @@ jobs: timeout_minutes: 40 command: | export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT252 }}/common/mono/Linux64/lib64:$LD_LIBRARY_PATH + export PYAEDT_LOCAL_SETTINGS_PATH='tests/pyaedt_settings.yaml' source .venv/bin/activate pytest ${{ env.PYTEST_ARGUMENTS }} -n 4 --dist loadfile --timeout=600 -m general @@ -551,6 +554,7 @@ jobs: uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2 env: PYTHONMALLOC: malloc + PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml' with: max_attempts: 2 retry_on: error @@ -632,6 +636,7 @@ jobs: timeout_minutes: 40 command: | export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT252 }}/common/mono/Linux64/lib64:$LD_LIBRARY_PATH + export PYAEDT_LOCAL_SETTINGS_PATH='tests/pyaedt_settings.yaml' source .venv/bin/activate pytest ${{ env.PYTEST_ARGUMENTS }} -n 4 --dist loadfile --timeout=600 -m visualization -x @@ -700,6 +705,7 @@ jobs: uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2 env: PYTHONMALLOC: malloc + PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml' with: max_attempts: 2 retry_on: error @@ -785,6 +791,7 @@ jobs: timeout_minutes: 120 command: | export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT252 }}/common/mono/Linux64/lib64:$LD_LIBRARY_PATH + export PYAEDT_LOCAL_SETTINGS_PATH='tests/pyaedt_settings.yaml' source .venv/bin/activate xvfb-run pytest ${{ env.PYTEST_ARGUMENTS }} --timeout=600 -m extensions @@ -853,6 +860,7 @@ jobs: uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2 env: PYTHONMALLOC: malloc + PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml' with: max_attempts: 2 retry_on: error @@ -926,6 +934,7 @@ jobs: uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2 env: PYTHONMALLOC: malloc + PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml' with: max_attempts: 2 retry_on: error From 117cb02a45ed22c589a4608902af53e8ccfc0f06 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Mon, 6 Oct 2025 13:20:11 +0200 Subject: [PATCH 15/18] Fixes --- .github/workflows/ci_cd.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 068552b2550..44706c34bf7 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -167,6 +167,8 @@ jobs: runs-on: ubuntu-latest steps: - name: Run unit tests + env: + PYAEDT_LOCAL_SETTINGS_PATH: 'tests/pyaedt_settings.yaml' uses: ansys/actions/tests-pytest@c2fa7c93f6883114e0e643599431b33d29f0b13f # v10.1.4 with: pytest-postargs: 'tests/unit' From 859a5ea36d24dab608a652bd65ed3c5442e785f9 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Wed, 8 Oct 2025 12:47:04 +0200 Subject: [PATCH 16/18] Refactor test marker assignment to use constants instead of string literals --- tests/conftest.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 9eb1b99cd3c..1bf91381842 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -118,24 +118,24 @@ def pytest_collection_modifyitems(config: pytest.Config, items: List[pytest.Item """Hook used to apply marker on tests.""" for item in items: # Mark unit, integration and system tests - if item.nodeid.startswith("UNIT_TEST_PREFIX"): + if item.nodeid.startswith(UNIT_TEST_PREFIX): item.add_marker(pytest.mark.unit) - elif item.nodeid.startswith("INTEGRATION_TEST_PREFIX"): + elif item.nodeid.startswith(INTEGRATION_TEST_PREFIX): item.add_marker(pytest.mark.integration) - elif item.nodeid.startswith("SYSTEM_TEST_PREFIX"): + elif item.nodeid.startswith(SYSTEM_TEST_PREFIX): item.add_marker(pytest.mark.system) # Finer markers for system tests - if item.nodeid.startswith("SYSTEM_SOLVERS_TEST_PREFIX"): + if item.nodeid.startswith(SYSTEM_SOLVERS_TEST_PREFIX): item.add_marker(pytest.mark.solvers) - elif item.nodeid.startswith("SYSTEM_GENERAL_TEST_PREFIX"): + elif item.nodeid.startswith(SYSTEM_GENERAL_TEST_PREFIX): item.add_marker(pytest.mark.general) - elif item.nodeid.startswith("VISUALIZATION_GENERAL_TEST_PREFIX"): + elif item.nodeid.startswith(VISUALIZATION_GENERAL_TEST_PREFIX): item.add_marker(pytest.mark.visualization) - elif item.nodeid.startswith("EXTENSIONS_GENERAL_TEST_PREFIX"): + elif item.nodeid.startswith(EXTENSIONS_GENERAL_TEST_PREFIX): item.add_marker(pytest.mark.extensions) - elif item.nodeid.startswith("FILTER_SOLUTIONS_TEST_PREFIX"): + elif item.nodeid.startswith(FILTER_SOLUTIONS_TEST_PREFIX): item.add_marker(pytest.mark.filter_solutions) - elif item.nodeid.startswith("EMIT_TEST_PREFIX"): + elif item.nodeid.startswith(EMIT_TEST_PREFIX): item.add_marker(pytest.mark.emit) From 11a1e9b89869b75bb5b409190d6d00f8d88f0733 Mon Sep 17 00:00:00 2001 From: Eduardo Blanco Date: Thu, 9 Oct 2025 10:47:00 +0200 Subject: [PATCH 17/18] Fixed example folders --- tests/conftest.py | 2 -- tests/system/conftest.py | 51 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 1bf91381842..35ff44c5e34 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -50,8 +50,6 @@ FILTER_SOLUTIONS_TEST_PREFIX = "tests/system/filter_solutions" EMIT_TEST_PREFIX = "tests/system/emit" -# Initialize default configuration - shared across all test types -os.environ["ANSYSEM_FEATURE_SS544753_ICEPAK_VIRTUALMESHREGION_PARADIGM_ENABLE"] = "1" DEFAULT_CONFIG = { "desktopVersion": "2025.2", diff --git a/tests/system/conftest.py b/tests/system/conftest.py index c516f8de80e..d41a9cc0709 100644 --- a/tests/system/conftest.py +++ b/tests/system/conftest.py @@ -34,9 +34,16 @@ from ansys.aedt.core.generic.file_utils import generate_unique_name from ansys.aedt.core.hfss import Hfss from tests import TESTS_GENERAL_PATH +from tests import TESTS_SOLVERS_PATH +from tests import TESTS_VISUALIZATION_PATH +from tests import TESTS_EXTENSIONS_PATH +from tests import TESTS_FILTER_SOLUTIONS_PATH from tests.conftest import NONGRAPHICAL from tests.conftest import config +# Initialize default configuration - shared across all test types +os.environ["ANSYSEM_FEATURE_SS544753_ICEPAK_VIRTUALMESHREGION_PARADIGM_ENABLE"] = "1" + @pytest.fixture(scope="module", autouse=True) def desktop(): @@ -51,14 +58,46 @@ def desktop(): return False +def _get_test_path_from_caller(): + """Determine the appropriate test path based on the calling test's location.""" + import inspect + + # Get the calling frame (skip this function and the fixture) + frame = inspect.currentframe() + try: + # Go up the call stack to find the test file + while frame: + filename = frame.f_code.co_filename + if 'test_' in os.path.basename(filename) and 'tests' in filename: + if 'visualization' in filename: + return TESTS_VISUALIZATION_PATH + elif 'solvers' in filename: + return TESTS_SOLVERS_PATH + elif 'extensions' in filename: + return TESTS_EXTENSIONS_PATH + elif 'filter_solutions' in filename: + return TESTS_FILTER_SOLUTIONS_PATH + else: + return TESTS_GENERAL_PATH + frame = frame.f_back + finally: + del frame + + # Default fallback + return TESTS_GENERAL_PATH + + @pytest.fixture(scope="module") def add_app(local_scratch): def _method( project_name=None, design_name=None, solution_type=None, application=None, subfolder="", just_open=False ): if project_name and not just_open: - example_project = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedt") - example_folder = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedb") + # Dynamically determine the correct test path + test_path = _get_test_path_from_caller() + + example_project = os.path.join(test_path, "example_models", subfolder, project_name + ".aedt") + example_folder = os.path.join(test_path, "example_models", subfolder, project_name + ".aedb") if os.path.exists(example_project): # Copy unit test project to scratch folder. Return full file path to the project without extension. test_project = local_scratch.copyfile(example_project) @@ -95,7 +134,9 @@ def _method( def test_project_file(local_scratch): def _method(project_name=None, subfolder=None): if subfolder: - project_file = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedt") + # Dynamically determine the correct test path + test_path = _get_test_path_from_caller() + project_file = os.path.join(test_path, "example_models", subfolder, project_name + ".aedt") else: project_file = os.path.join(local_scratch.path, project_name + ".aedt") if os.path.exists(project_file): @@ -110,7 +151,9 @@ def _method(project_name=None, subfolder=None): def add_edb(local_scratch): def _method(project_name=None, subfolder=""): if project_name: - example_folder = os.path.join(TESTS_GENERAL_PATH, "example_models", subfolder, project_name + ".aedb") + # Dynamically determine the correct test path + test_path = _get_test_path_from_caller() + example_folder = os.path.join(test_path, "example_models", subfolder, project_name + ".aedb") if os.path.exists(example_folder): target_folder = os.path.join(local_scratch.path, project_name + ".aedb") local_scratch.copyfolder(example_folder, target_folder) From 84ad71b971a6268900560e7cf155705cb7a10c12 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 08:47:50 +0000 Subject: [PATCH 18/18] CHORE: Auto fixes from pre-commit hooks --- tests/system/conftest.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/system/conftest.py b/tests/system/conftest.py index d41a9cc0709..59bd4a4bde8 100644 --- a/tests/system/conftest.py +++ b/tests/system/conftest.py @@ -33,11 +33,11 @@ from ansys.aedt.core.filtersolutions import LumpedDesign from ansys.aedt.core.generic.file_utils import generate_unique_name from ansys.aedt.core.hfss import Hfss +from tests import TESTS_EXTENSIONS_PATH +from tests import TESTS_FILTER_SOLUTIONS_PATH from tests import TESTS_GENERAL_PATH from tests import TESTS_SOLVERS_PATH from tests import TESTS_VISUALIZATION_PATH -from tests import TESTS_EXTENSIONS_PATH -from tests import TESTS_FILTER_SOLUTIONS_PATH from tests.conftest import NONGRAPHICAL from tests.conftest import config @@ -61,28 +61,28 @@ def desktop(): def _get_test_path_from_caller(): """Determine the appropriate test path based on the calling test's location.""" import inspect - + # Get the calling frame (skip this function and the fixture) frame = inspect.currentframe() try: # Go up the call stack to find the test file while frame: filename = frame.f_code.co_filename - if 'test_' in os.path.basename(filename) and 'tests' in filename: - if 'visualization' in filename: + if "test_" in os.path.basename(filename) and "tests" in filename: + if "visualization" in filename: return TESTS_VISUALIZATION_PATH - elif 'solvers' in filename: + elif "solvers" in filename: return TESTS_SOLVERS_PATH - elif 'extensions' in filename: + elif "extensions" in filename: return TESTS_EXTENSIONS_PATH - elif 'filter_solutions' in filename: + elif "filter_solutions" in filename: return TESTS_FILTER_SOLUTIONS_PATH else: return TESTS_GENERAL_PATH frame = frame.f_back finally: del frame - + # Default fallback return TESTS_GENERAL_PATH @@ -95,7 +95,7 @@ def _method( if project_name and not just_open: # Dynamically determine the correct test path test_path = _get_test_path_from_caller() - + example_project = os.path.join(test_path, "example_models", subfolder, project_name + ".aedt") example_folder = os.path.join(test_path, "example_models", subfolder, project_name + ".aedb") if os.path.exists(example_project):