@@ -753,6 +753,98 @@ def test_channel_tuple_names(dci: DummyChannelInstrument) -> None:
753753 assert dci .channels .full_name == "dci_TempSensors"
754754
755755
756+ def test_multi_parameter_returns_multichannel_parameter (
757+ dci : DummyChannelInstrument ,
758+ ) -> None :
759+ """Test that multi_parameter returns a MultiChannelInstrumentParameter for valid parameter name."""
760+ temp_multi_param = dci .channels .multi_parameter ("temperature" )
761+ assert isinstance (temp_multi_param , MultiChannelInstrumentParameter )
762+
763+ temperatures = temp_multi_param .get ()
764+ assert len (temperatures ) == 6
765+
766+
767+ def test_multi_parameter_invalid_name_raises (dci : DummyChannelInstrument ) -> None :
768+ """Test that multi_parameter raises AttributeError for invalid parameter name."""
769+ with pytest .raises (
770+ AttributeError ,
771+ match = "'ChannelTuple' object has no parameter 'nonexistent_param'" ,
772+ ):
773+ dci .channels .multi_parameter ("nonexistent_param" )
774+
775+
776+ def test_multi_parameter_on_empty_channel_tuple_raises (
777+ empty_instrument : Instrument ,
778+ ) -> None :
779+ """Test that multi_parameter raises AttributeError on empty channel tuple."""
780+ channels = ChannelTuple (empty_instrument , "channels" , chan_type = DummyChannel )
781+ empty_instrument .add_submodule ("channels" , channels )
782+
783+ with pytest .raises (
784+ AttributeError ,
785+ match = "'ChannelTuple' object has no parameter 'temperature'" ,
786+ ):
787+ channels .multi_parameter ("temperature" )
788+
789+
790+ def test_multi_function_returns_callable (dci : DummyChannelInstrument ) -> None :
791+ """Test that multi_function returns a callable for valid function name."""
792+ multi_func = dci .channels .multi_function ("log_my_name" )
793+ assert callable (multi_func )
794+
795+
796+ def test_multi_function_calls_function_on_all_channels (
797+ dci : DummyChannelInstrument , caplog : LogCaptureFixture
798+ ) -> None :
799+ """Test that the returned callable calls the function on all channels."""
800+ with caplog .at_level (
801+ logging .DEBUG , logger = "qcodes.instrument_drivers.mock_instruments"
802+ ):
803+ caplog .clear ()
804+ multi_func = dci .channels .multi_function ("log_my_name" )
805+ multi_func ()
806+ mssgs = [rec .message for rec in caplog .records ]
807+ names = [ch .name .replace ("dci_" , "" ) for ch in dci .channels ]
808+ assert mssgs == names
809+
810+
811+ def test_multi_function_with_callable_method (
812+ dci : DummyChannelInstrument , mocker : "pytest_mock.MockerFixture"
813+ ) -> None :
814+ """Test that multi_function works with callable methods on channels."""
815+ for channel in dci .channels :
816+ channel .turn_on = mocker .MagicMock (return_value = 1 )
817+
818+ multi_func = dci .channels .multi_function ("turn_on" )
819+ result = multi_func ("bar" )
820+ assert result is None
821+ for channel in dci .channels :
822+ channel .turn_on .assert_called_with ("bar" ) # type: ignore[union-attr]
823+
824+
825+ def test_multi_function_invalid_name_raises (dci : DummyChannelInstrument ) -> None :
826+ """Test that multi_function raises AttributeError for invalid function/callable name."""
827+ with pytest .raises (
828+ AttributeError ,
829+ match = "'ChannelTuple' object has no callable or function 'nonexistent_func'" ,
830+ ):
831+ dci .channels .multi_function ("nonexistent_func" )
832+
833+
834+ def test_multi_function_on_empty_channel_tuple_raises (
835+ empty_instrument : Instrument ,
836+ ) -> None :
837+ """Test that multi_function raises AttributeError on empty channel tuple."""
838+ channels = ChannelTuple (empty_instrument , "channels" , chan_type = DummyChannel )
839+ empty_instrument .add_submodule ("channels" , channels )
840+
841+ with pytest .raises (
842+ AttributeError ,
843+ match = "'ChannelTuple' object has no callable or function 'temperature'" ,
844+ ):
845+ channels .multi_function ("temperature" )
846+
847+
756848def _verify_multiparam_data (data ) -> None :
757849 assert "multi_setpoint_param_this_setpoint_set" in data .arrays .keys ()
758850 assert_array_equal (
0 commit comments