Skip to content

Commit 5c9105f

Browse files
added doc strings to test and test name change to automated test
1 parent fc0a57d commit 5c9105f

10 files changed

Lines changed: 50 additions & 23 deletions

.github/workflows/joss_tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ on:
88

99
jobs:
1010
test:
11+
name: automated test
1112
runs-on: ubuntu-latest
1213

1314
steps:

.github/workflows/python-app.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,6 @@ jobs:
4949
# 6. Run Tests (The "Logic" Check)
5050
# We ignore the visual GUI rendering tests if they are too heavy,
5151
# but since we mocked them, they should run fast!
52-
- name: Test with pytest
52+
- name: automated test
5353
run: |
5454
python -m pytest tests/

tests/test_backends_logic.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"""
2-
tests/test_backends_logic.py
2+
Purpose: Structure verification for control scripts.
33
4-
This file tests the LOGIC of the backends without connecting to hardware.
5-
It is designed to handle Classes, Scripts with main(), or loose Procedural Scripts.
4+
What it does: Analyzes your backend files to determine if they are classes, procedural scripts, or functions, and attempts to run them in a "dry" mode to verify their logic structure.
65
"""
76

87
import pytest

tests/test_deep_simulation.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""
2+
Purpose: Robustness and loop safety (Circuit Breakers).
3+
4+
What it does: Runs full measurement scripts while mocking time.sleep to prevent infinite loops. It acts as a "watchdog," forcing scripts to exit if they run too long, ensuring your while True loops don't freeze the test server.
5+
"""
16
import unittest
27
import sys
38
import os
@@ -94,7 +99,7 @@ def test_01_k2400_iv_backend(self):
9499

95100
with patch('pymeasure.instruments.keithley.Keithley2400') as MockInst:
96101
spy = MockInst.return_value
97-
with patch('builtins.input', side_effect=['100', '10', 'test_file']), \
102+
with patch('builtins.input', side_effect=['100', '10', 'test_file']),
98103
patch('pandas.DataFrame.to_csv'):
99104
self.run_module_safely(
100105
"Keithley_2400.Backends.IV_K2400_Loop_Backend_v10", {})
@@ -110,7 +115,7 @@ def test_02_lakeshore_backend(self):
110115
spy.query.side_effect = [
111116
"LSCI,MODEL350,0,0"] + ["10.0", "300.0"] * 20
112117

113-
with patch('builtins.input', side_effect=['10', '300', '10', '350']), \
118+
with patch('builtins.input', side_effect=['10', '300', '10', '350']),
114119
patch('builtins.open', mock_open()):
115120
self.run_module_safely("Lakeshore_350_340.Backends.T_Control_L350_Simple_Backend_v10", {})
116121

@@ -149,7 +154,7 @@ def test_05_delta_simple(self):
149154
with patch('pyvisa.ResourceManager') as MockRM:
150155
MockRM.return_value.open_resource.return_value
151156
inputs = ['0', '1e-5', '1e-6', 'test_file', 'y', 'y']
152-
with patch('builtins.input', side_effect=inputs), \
157+
with patch('builtins.input', side_effect=inputs),
153158
patch('pandas.DataFrame.to_csv'):
154159
self.run_module_safely("Delta_mode_Keithley_6221_2182.Backends.Delta_K6221_K2182_Simple_v7", {})
155160

@@ -163,7 +168,7 @@ def test_06_delta_sensing(self):
163168
inst = MockRM.return_value.open_resource.return_value
164169
inst.query.return_value = "+1.23E-5"
165170
inputs = ['10', '300', '10', 'test_file', 'y']
166-
with patch('builtins.input', side_effect=inputs), \
171+
with patch('builtins.input', side_effect=inputs),
167172
patch('pandas.DataFrame.to_csv'):
168173
try:
169174
self.run_module_safely(
@@ -206,7 +211,7 @@ def test_08_combined_2400_2182(self):
206211
# Add extra inputs just in case the script asks for more than
207212
# expected
208213
inputs = ['10', '1', 'test_file', 'y', 'y', 'y', 'y']
209-
with patch('builtins.input', side_effect=inputs), \
214+
with patch('builtins.input', side_effect=inputs),
210215
patch('pandas.DataFrame.to_csv'):
211216
self.run_module_safely(
212217
"Keithley_2400_Keithley_2182.Backends.IV_K2400_K2182_Backend_v1", {})
@@ -237,7 +242,7 @@ def test_10_high_resistance(self):
237242
# Correct inputs for: start_v, stop_v, steps, delay, filename
238243
inputs = ['-10', '10', '5', '0.1', 'test_file']
239244

240-
with patch('builtins.input', side_effect=inputs), \
245+
with patch('builtins.input', side_effect=inputs),
241246
patch('builtins.open', mock_open()):
242247
self.run_module_safely("Keithley_6517B.High_Resistance.Backends.IV_K6517B_Simple_Backend_v10", {}) # noqa
243248

@@ -261,10 +266,10 @@ def test_12_gpib_rescue(self):
261266
self.addCleanup(mock_sleep.stop)
262267

263268
rm = MockRM.return_value
264-
rm.list_resources.return_value = ('GPIB0::1::INSTR',)
269+
rm.list_.resources.return_value = ('GPIB0::1::INSTR',)
265270
self.run_module_safely(
266271
"Utilities.GPIB_Interface_Rescue_Simple_Backened_v2_", {})
267272

268273

269274
if __name__ == '__main__':
270-
unittest.main()
275+
unittest.main()

tests/test_full_stack_simulation.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""
2+
Purpose: End-to-end protocol verification.
3+
4+
What it does: Simulates specific instrument responses (e.g., feeding fake temperature data like "10.0, 50.0" to the Lakeshore script) and verifies that the script sends the correct commands back (e.g., "HTRSET").
5+
"""
16
import unittest
27

38
import os
@@ -153,4 +158,4 @@ def test_gpib_scanner_loop(self):
153158

154159

155160
if __name__ == '__main__':
156-
unittest.main()
161+
unittest.main()

tests/test_gui_layouts.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
2-
tests/test_gui_layouts.py
3-
Tests GUI instantiation by deeply patching the Matplotlib Figure class.
2+
Purpose: GUI instantiation stability.
3+
4+
What it does: Attempts to build the GUI windows in memory. It uses a "Safe" mock for Matplotlib to prevent graphing errors from crashing the test, ensuring the layout logic is sound.
45
"""
56
import pytest
67
import os

tests/test_gui_modules_initialization.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""
2+
Purpose: Module-level GUI smoke tests.
3+
4+
What it does: Dynamically finds all files ending in _GUI.py, imports them, and tries to initialize their main class to ensure they don't crash on startup.
5+
"""
16
import pytest
27
import os
38
import sys
@@ -64,4 +69,4 @@ def test_gui_module_initialization(module_path):
6469
assert app_instance is not None, "GUI class failed to instantiate."
6570

6671
except (ImportError, AttributeError, Exception) as e:
67-
pytest.fail(f"Failed to initialize GUI module '{module_path}'.\nError: {e}")
72+
pytest.fail(f"Failed to initialize GUI module '{module_path}'.\nError: {e}")

tests/test_package_integrity.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""
2+
Purpose: Basic code health checks.
3+
4+
What it does: Compiles every Python file to catch syntax errors and checks if every file has a top-level docstring (a JOSS requirement).
5+
"""
16
import pytest
27
import os
38
import ast
@@ -71,11 +76,12 @@ def test_has_docstring(file_path):
7176
tree = ast.parse(source)
7277
# Check if the first node in the file is a Docstring (Expression -> Constant string)
7378
if not (tree.body and isinstance(tree.body[0], ast.Expr) and
74-
isinstance(tree.body[0].value, (ast.Str, ast.Constant))):
79+
isinstance(tree.body[0].value, (ast.Str, ast.Constant))):
80+
7581
# This is a 'Warning' - it won't break code, but it fails JOSS standards
7682
warnings.warn(f"JOSS STANDARD MISSING: {os.path.basename(file_path)} has no top-level docstring. "
77-
"Please add a description at the top of the file using '\"\"\" ... \"\"\"'.", UserWarning)
83+
"Please add a description at the top of the file using '""" ... """'.", UserWarning)
7884

7985
except SyntaxError:
8086
# Syntax errors are handled by the other test
81-
pass
87+
pass

tests/test_pica_launcher.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""
2+
Purpose: Entry-point testing.
3+
4+
What it does: Tests the main PICALauncherApp, mocking heavy dependencies like Pillow (images) and fonts to ensure the main menu launches correctly.
5+
"""
16
import pytest
27
import os
38
import sys
@@ -45,4 +50,4 @@ def test_pica_launcher_initialization(mock_app_dependencies):
4550
assert app.root == mock_root
4651
assert app is not None
4752

48-
print("\n[SUCCESS] PICALauncherApp initialized safely with Mock Tk and Mock Font.")
53+
print("\n[SUCCESS] PICALauncherApp initialized safely with Mock Tk and Mock Font.")

tests/test_utilities_logic.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
2-
tests/test_utilities_logic.py
3-
Tests the logic inside the Utilities folder (Plotters, Formatters)
4-
without needing a GUI or Hardware.
2+
Purpose: Logic checks for helper tools.
3+
4+
What it does: Verifies that the LivePlotter correctly appends data to arrays and that formatting utilities define the correct fonts/styles.
55
"""
66
import pytest
77
from unittest.mock import MagicMock, patch

0 commit comments

Comments
 (0)