Skip to content

Commit

Permalink
Tests for Yokogawa 7651 and tests + BF for Yokogawa 6370 (#251)
Browse files Browse the repository at this point in the history
- Full test suite for Yokogawa 7651
- Extended test suite for Yokogawa 6370 for complete coverage
- Found two small bugs in Yokogawa 6370:
  - Routines `data` and `wavelength`, both return the data for the
    active trace, returned the method itself instead of the data.
  - These were also the two untested routines.
  • Loading branch information
trappitsch authored Aug 25, 2020
1 parent 64093e5 commit 4c1a67c
Show file tree
Hide file tree
Showing 3 changed files with 295 additions and 2 deletions.
232 changes: 232 additions & 0 deletions instruments/tests/test_yokogawa/test_yokogawa7651.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Unit tests for the Yokogawa 7651 power supply
"""

# IMPORTS #####################################################################


import pytest

import instruments as ik
import instruments.units as u
from instruments.tests import expected_protocol


# TESTS #######################################################################

# pylint: disable=protected-access

# TEST CHANNEL #


def test_channel_init():
"""Initialize of channel class."""
with expected_protocol(
ik.yokogawa.Yokogawa7651,
[
],
[
]
) as yok:
assert yok.channel[0]._parent is yok
assert yok.channel[0]._name == 0


def test_channel_mode():
"""Get / Set mode of the channel."""
with expected_protocol(
ik.yokogawa.Yokogawa7651,
[
"F5;",
"E;", # trigger
"F1;",
"E;" # trigger
],
[
]
) as yok:
# query
with pytest.raises(NotImplementedError) as exc_info:
print(f"Mode is: {yok.channel[0].mode}")
exc_msg = exc_info.value.args[0]
assert exc_msg == "This instrument does not support querying the " \
"operation mode."

# set first current, then voltage mode
yok.channel[0].mode = yok.Mode.current
yok.channel[0].mode = yok.Mode.voltage


def test_channel_invalid_mode_set():
"""Set mode to invalid value."""
with expected_protocol(
ik.yokogawa.Yokogawa7651,
[
],
[
]
) as yok:
wrong_mode = 42
with pytest.raises(TypeError) as exc_info:
yok.channel[0].mode = wrong_mode
exc_msg = exc_info.value.args[0]
assert exc_msg == "Mode setting must be a `Yokogawa7651.Mode` " \
"value, got {} instead.".format(type(wrong_mode))


def test_channel_voltage():
"""Get / Set voltage of channel."""

# values to set for test
value_unitless = 5.
value_unitful = u.Quantity(500, u.mV)

with expected_protocol(
ik.yokogawa.Yokogawa7651,
[
"F1;\nE;", # set voltage mode
f"SA{value_unitless};",
"E;", # trigger
"F1;\nE;", # set voltage mode
f"SA{value_unitful.rescale(u.volt).magnitude};",
"E;" # trigger
],
[
]
) as yok:
# query
with pytest.raises(NotImplementedError) as exc_info:
print(f"Voltage is: {yok.channel[0].voltage}")
exc_msg = exc_info.value.args[0]
assert exc_msg == "This instrument does not support querying the " \
"output voltage setting."

# set first current, then voltage mode
yok.channel[0].voltage = value_unitless
yok.channel[0].voltage = value_unitful


def test_channel_current():
"""Get / Set current of channel."""

# values to set for test
value_unitless = 0.8
value_unitful = u.Quantity(50, u.mA)

with expected_protocol(
ik.yokogawa.Yokogawa7651,
[
"F5;\nE;", # set voltage mode
f"SA{value_unitless};",
"E;", # trigger
"F5;\nE;", # set voltage mode
f"SA{value_unitful.rescale(u.A).magnitude};",
"E;" # trigger
],
[
]
) as yok:
# query
with pytest.raises(NotImplementedError) as exc_info:
print(f"Current is: {yok.channel[0].current}")
exc_msg = exc_info.value.args[0]
assert exc_msg == "This instrument does not support querying the " \
"output current setting."

# set first current, then current mode
yok.channel[0].current = value_unitless
yok.channel[0].current = value_unitful


def test_channel_output():
"""Get / Set output of channel."""
with expected_protocol(
ik.yokogawa.Yokogawa7651,
[
"O1;", # turn output on
"E;",
"O0;", # turn output off
"E;"
],
[
]
) as yok:
# query
with pytest.raises(NotImplementedError) as exc_info:
print(f"Output is: {yok.channel[0].output}")
exc_msg = exc_info.value.args[0]
assert exc_msg == "This instrument does not support querying the " \
"output status."

# set first current, then current mode
yok.channel[0].output = True
yok.channel[0].output = False


# CLASS PROPERTIES #


def test_voltage():
"""Get / Set voltage of instrument."""

# values to set for test
value_unitless = 5.
value_unitful = u.Quantity(500, u.mV)

with expected_protocol(
ik.yokogawa.Yokogawa7651,
[
"F1;\nE;", # set voltage mode
f"SA{value_unitless};",
"E;", # trigger
"F1;\nE;", # set voltage mode
f"SA{value_unitful.rescale(u.volt).magnitude};",
"E;" # trigger
],
[
]
) as yok:
# query
with pytest.raises(NotImplementedError) as exc_info:
print(f"Voltage is: {yok.voltage}")
exc_msg = exc_info.value.args[0]
assert exc_msg == "This instrument does not support querying the " \
"output voltage setting."

# set first current, then voltage mode
yok.voltage = value_unitless
yok.voltage = value_unitful


def test_current():
"""Get / Set current of instrument."""

# values to set for test
value_unitless = 0.8
value_unitful = u.Quantity(50, u.mA)

with expected_protocol(
ik.yokogawa.Yokogawa7651,
[
"F5;\nE;", # set current mode
f"SA{value_unitless};",
"E;", # trigger
"F5;\nE;", # set current mode
f"SA{value_unitful.rescale(u.A).magnitude};",
"E;" # trigger
],
[
]
) as yok:
# query
with pytest.raises(NotImplementedError) as exc_info:
print(f"current is: {yok.current}")
exc_msg = exc_info.value.args[0]
assert exc_msg == "This instrument does not support querying the " \
"output current setting."

# set first current, then current mode
yok.current = value_unitless
yok.current = value_unitful
61 changes: 61 additions & 0 deletions instruments/tests/test_yokogawa/test_yokogawa_6370.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,67 @@ def test_active_trace():
assert inst.active_trace == inst.Traces.G


# METHODS #


@given(values=st.lists(st.decimals(allow_infinity=False, allow_nan=False),
min_size=1))
def test_data_active_trace(values):
"""Get data from active trace - method."""
values_packed = b"".join(struct.pack("<d", value) for value in values)
values_len = str(len(values_packed)).encode()
values_len_of_len = str(len(values_len)).encode()
channel = "TRA" # active trace
with expected_protocol(
ik.yokogawa.Yokogawa6370,
[
":FORMat:DATA REAL,64",
":TRAC:Y? {}".format(channel),
":TRAC:ACTIVE?",
":TRAC:Y? {}".format(channel)
],
[
b"#" + values_len_of_len + values_len + values_packed,
channel,
b"#" + values_len_of_len + values_len + values_packed
]
) as inst:
# data by channel
data_call_by_trace = inst.channel[channel].data()
# call active trace data
data_active_trace = inst.data()
assert (data_call_by_trace == data_active_trace).all()


@given(values=st.lists(st.decimals(allow_infinity=False, allow_nan=False),
min_size=1))
def test_wavelength_active_trace(values):
"""Get wavelength from active trace - method."""
values_packed = b"".join(struct.pack("<d", value) for value in values)
values_len = str(len(values_packed)).encode()
values_len_of_len = str(len(values_len)).encode()
channel = "TRA" # active trace
with expected_protocol(
ik.yokogawa.Yokogawa6370,
[
":FORMat:DATA REAL,64",
":TRAC:X? {}".format(channel),
":TRAC:ACTIVE?",
":TRAC:X? {}".format(channel)
],
[
b"#" + values_len_of_len + values_len + values_packed,
channel,
b"#" + values_len_of_len + values_len + values_packed
]
) as inst:
# data by channel
data_call_by_trace = inst.channel[channel].wavelength()
# call active trace data
data_active_trace = inst.wavelength()
assert (data_call_by_trace == data_active_trace).all()


def test_start_sweep():
with expected_protocol(
ik.yokogawa.Yokogawa6370,
Expand Down
4 changes: 2 additions & 2 deletions instruments/yokogawa/yokogawa6370.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,13 @@ def data(self):
"""
Function to query the active Trace data of the OSA.
"""
return self.channel[self.active_trace].data
return self.channel[self.active_trace].data()

def wavelength(self):
"""
Query the wavelength axis of the active trace.
"""
return self.channel[self.active_trace].wavelength
return self.channel[self.active_trace].wavelength()

def start_sweep(self):
"""
Expand Down

0 comments on commit 4c1a67c

Please sign in to comment.