1+ # tests/conftest.py
2+ """
3+ This file contains shared fixtures for the PICA test suite.
4+ Fixtures defined here are automatically available to all test files.
5+ """
16import pytest
2- import matplotlib
7+ from unittest .mock import MagicMock , patch
8+ import sys
39
4- # Force matplotlib to not use any X11/Windows GUI backend
5- # This prevents "KeyError" and display issues during testing
6- matplotlib .use ('Agg' )
710
11+ @pytest .fixture
12+ def mock_tkinter ():
13+ """
14+ A comprehensive pytest fixture that mocks essential libraries (tkinter,
15+ matplotlib, pyvisa, etc.) to prevent any actual GUI rendering or hardware
16+ communication during tests. This is crucial for CI/CD environments.
817
9- @pytest .fixture (autouse = True )
10- def reset_matplotlib_params ():
11- """Ensures matplotlib config is clean for every test."""
12- matplotlib .rcdefaults ()
18+ It correctly mocks matplotlib as a package to allow submodule imports
19+ like 'from matplotlib.figure import Figure'.
20+ """
21+ # Create a mock for matplotlib that acts like a package
22+ mock_matplotlib = MagicMock ()
23+ mock_matplotlib .figure .Figure = MagicMock ()
24+ mock_matplotlib .backends .backend_tkagg .FigureCanvasTkAgg = MagicMock (
25+ return_value = MagicMock (get_tk_widget = MagicMock ())
26+ )
27+
28+ # Create a mock for pymeasure that acts like a package
29+ mock_pymeasure = MagicMock ()
30+ mock_pymeasure .instruments .keithley .Keithley2400 = MagicMock ()
31+ mock_pymeasure .instruments .keithley .Keithley6517B = MagicMock ()
32+ mock_pymeasure .instruments .agilent .AgilentE4980 = MagicMock ()
33+
34+ # Mock libraries that would otherwise create windows or require hardware
35+ mocked_modules = {
36+ 'tkinter' : MagicMock (),
37+ 'tkinter.ttk' : MagicMock (),
38+ 'tkinter.messagebox' : MagicMock (),
39+ 'tkinter.filedialog' : MagicMock (),
40+ 'tkinter.simpledialog' : MagicMock (),
41+ 'tkinter.font' : MagicMock (),
42+ 'matplotlib' : mock_matplotlib ,
43+ 'matplotlib.pyplot' : MagicMock (),
44+ 'matplotlib.figure' : mock_matplotlib .figure ,
45+ 'matplotlib.backends' : mock_matplotlib .backends ,
46+ 'matplotlib.backends.backend_tkagg' : mock_matplotlib .backends .backend_tkagg ,
47+ 'pyvisa' : MagicMock (), # Mock pyvisa
48+ 'pymeasure' : mock_pymeasure ,
49+ 'pymeasure.instruments' : mock_pymeasure .instruments ,
50+ 'pymeasure.instruments.keithley' : mock_pymeasure .instruments .keithley ,
51+ 'PIL' : MagicMock (),
52+ 'PIL.Image' : MagicMock (),
53+ 'PIL.ImageTk' : MagicMock (),
54+ }
55+ with patch .dict ('sys.modules' , {
56+ ** mocked_modules ,
57+ 'sys' : sys .modules ['sys' ],
58+ 'warnings' : sys .modules ['warnings' ],
59+ }) as patched_modules :
60+ yield
0 commit comments