RoboAide
Project to improve a DIY robotic arm used for mobility assistance
test_ui.py
Go to the documentation of this file.
1 import unittest
2 import sys
3 import time
4 import json
5 
6 from ui import RoboAide
7 from ui.Drawer import Drawer
8 from PySide2.QtWidgets import QApplication
9 from PySide2.QtWidgets import QComboBox
10 
11 # based on : https://bitbucket.org/jmcgeheeiv/pyqttestexample/src/default/src/
12 
13 # Start a Qt App to create a window
14 app = QApplication(sys.argv)
15 
16 class TestMove(unittest.TestCase):
17  def setUp(self):
18  self.testWindow = RoboAide.MainWindow(app)
19  self.testWindow.serialConnected = True
20  self.testWindow.comm = DummyComm()
21  self.testMove = RoboAide.Move(self.testWindow.dictMot)
22 
23  def test_get_position(self):
24  for motor in self.testWindow.dictMot:
25  self.assertEqual(self.testMove.getMotorPosition(motor), -1)
26 
27  def test_set_position(self):
28  for motor in self.testWindow.dictMot:
29  self.testMove.setMotorPosition(motor,10)
30 
31  for motor in self.testWindow.dictMot:
32  self.assertEqual(self.testMove.getMotorPosition(motor), 10)
33 
35  self.assertEqual(self.testMove.getMotorPosition("moteur 1"), "There's no motor named that way")
36 
37 class TestMotor(unittest.TestCase):
38  def setUp(self):
39  self.testWindow = RoboAide.MainWindow(app)
40  self.testWindow.serialConnected = True
41  self.testWindow.comm = DummyComm()
42  # self.testWindow.msgTransmission.start()
43  self.testMotor = RoboAide.Motor(self.testWindow, "testMotor", 500, True)
44 
45  def test_get_position(self):
46  self.assertEqual(self.testMotor.getGoalPosition(), 500)
47 
48  def test_is_enabled(self):
49  self.assertTrue(self.testMotor.isEnabled(),"Motor is not enabled")
50 
51  def test_set_status(self):
52  self.testMotor.setStatus(False)
53  self.assertFalse(self.testMotor.isEnabled(),"Motor is enabled, set status doesn't work")
54 
55  def test_get_name(self):
56  self.assertEqual(self.testMotor.getName(),"testMotor")
57 
58  def test_set_name(self):
59  self.testMotor.setName("Nom")
60  self.assertEqual(self.testMotor.getName(),"Nom")
61 
62 class TestSequence(unittest.TestCase):
63  def setUp(self):
64  self.testWindow = RoboAide.MainWindow(app)
65  self.testWindow.serialConnected = True
66  self.testWindow.comm = DummyComm()
67  self.testSequence = RoboAide.Sequence(self.testWindow.dictMot,"testSequence")
68 
69  def test_getName(self):
70  self.assertEqual(self.testSequence.getName(),"testSequence")
71 
72  def test_setName(self):
73  self.testSequence.setName("pogo")
74  self.assertEqual(self.testSequence.getName(),"pogo")
75 
77  self.assertEqual(self.testSequence.getNumberofMoves(), 0)
78 
79  def test_addMove(self):
80  self.testSequence.addMove(RoboAide.Move(self.testWindow.dictMot))
81  self.assertEqual(self.testSequence.getNumberofMoves(), 1)
82 
83  def test_getMoves(self):
84  self.testSequence.addMove(RoboAide.Move(self.testWindow.dictMot))
85  self.testSequence.addMove(RoboAide.Move(self.testWindow.dictMot))
86  self.assertEqual(self.testSequence.getNumberofMoves(), 2)
87 
88  def test_deleteMove(self):
89  move = RoboAide.Move(self.testWindow.dictMot)
90  self.testSequence.addMove(move)
91  self.testSequence.deleteMove(move)
92  self.assertEqual(self.testSequence.getNumberofMoves(), 0)
93 
94 class TestCreateSequenceWindow(unittest.TestCase):
95  def setUp(self):
96  self.testWindow = RoboAide.MainWindow(app)
97  self.testWindow.serialConnected = True
98  self.testWindow.comm = DummyComm()
99  self.testSequenceWindow = RoboAide.CreateSequenceWindow(self.testWindow.dictMot,
100  self.testWindow.listOfSequencesHandler,
101  RoboAide.Sequence(self.testWindow.dictMot))
102 
104 
105  for counterMotors in range(len(self.testWindow.dictMot)):
106  self.testSequenceWindow.listOfSliders[counterMotors].setValue(40)
107 
108  self.testSequenceWindow.addMovetoSequence()
109 
110  self.assertEqual(self.testSequenceWindow.getSequence().getNumberofMoves(),1)
111 
112 
114  for motor in self.testWindow.dictMot:
115  self.testWindow.dictMot[motor].setGoalPosition(30)
116 
117  self.testSequenceWindow.updateSlidersPositions()
118 
119  for counterMotors in range(len(self.testWindow.dictMot)):
120  self.assertEqual(self.testSequenceWindow.listOfSliders[counterMotors].value(),30)
121 
122  def test_deleteMove(self):
123  for counterMotors in range(len(self.testWindow.dictMot)):
124  self.testSequenceWindow.listOfSliders[counterMotors].setValue(40)
125 
126  self.testSequenceWindow.addMovetoSequence()
127 
128  self.assertEqual(self.testSequenceWindow.getSequence().getNumberofMoves(),1)
129 
130  self.testSequenceWindow.deleteMove(self.testSequenceWindow.getListofMoveLabels().item(0))
131 
132  self.assertEqual(self.testSequenceWindow.getSequence().getNumberofMoves(), 0)
133 
134  def test_setName(self):
135  self.testSequenceWindow.setName("bob")
136  self.assertEqual(self.testSequenceWindow.getSequence().getName(), "bob")
137 
139  row = self.testWindow.ui.listOfSequences.count()
140 
141  for counterMotors in range(len(self.testWindow.dictMot)):
142  self.testSequenceWindow.listOfSliders[counterMotors].setValue(40)
143  self.testSequenceWindow.nameEntry.setText("bob")
144  self.testSequenceWindow.addMovetoSequence()
145 
146  self.testSequenceWindow.addSequenceToList()
147 
148  self.assertEqual(self.testWindow.ui.listOfSequences.count(), row+1)
149 
150  foundSequenceInSaveFile = False
151  try:
152  with open('SaveSequence.json') as save:
153  savedListOfSequences = json.load(save)
154  for sequence in savedListOfSequences:
155  if self.testSequenceWindow.getSequence().getName() in sequence:
156  foundSequenceInSaveFile = True
157 
158  self.assertTrue(foundSequenceInSaveFile)
159  except FileNotFoundError:
160  print("No file saved")
161 
162  self.testWindow.ui.listOfSequences.setCurrentItem(self.testSequenceWindow.getSequence())
163 
164  self.testWindow.listOfSequencesHandler.removeSelectedItem()
165 
166  self.assertEqual(self.testWindow.ui.listOfSequences.count(), row)
167 
168 class TestListOfSequencesHandler(unittest.TestCase):
169  def setUp(self):
170  self.testWindow = RoboAide.MainWindow(app)
171  self.testWindow.serialConnected = True
172  self.testWindow.comm = DummyComm()
173  self.testListofSequencesHandler = RoboAide.ListOfSequencesHandler(self.testWindow,
174  self.testWindow.dictMot)
175  self.testSequence = RoboAide.Sequence(self.testWindow.dictMot, "testSequence")
176  self.testMove = RoboAide.Move(self.testWindow.dictMot)
177  for motor in self.testWindow.dictMot:
178  self.testMove.setMotorPosition(motor,10)
179  self.testSequence.addMove(self.testMove)
180 
181  def test_addItem(self):
182  row = self.testWindow.ui.listOfSequences.count()
183  self.testListofSequencesHandler.addItem(self.testSequence)
184  self.assertEqual(self.testWindow.ui.listOfSequences.count(), row + 1)
185 
186 
187  def test_playSequence(self):
188  row = self.testWindow.ui.listOfSequences.count()
189  self.testListofSequencesHandler.addItem(self.testSequence)
190  self.testWindow.ui.listOfSequences.setCurrentItem(self.testWindow.ui.listOfSequences.item(row))
191  self.assertTrue(self.testWindow.ui.listOfSequences.item(row).isSelected())
192  self.testListofSequencesHandler.playSequence()
193  time.sleep(1)
194  self.testWindow.shouldStop = True
195  for motor in self.testWindow.dictMot:
196  self.assertEqual(self.testWindow.dictMot[motor].getGoalPosition(),10)
197 
198 
199 
200 
201 class TestMainWindow(unittest.TestCase):
202  def setUp(self):
203  self.testWindow = RoboAide.MainWindow(app)
204  self.testWindow.serialConnected = True
205 
206  def test_sendMessage(self):
207  # This test needs to be updated everytime the struct is modified.
208  # More specifically, every instance of expectedResult needs to be updated.
209  # send absolute move message for every motor
210  i = 0
211  valueList = [0, 0, 0, 0, 0, 0]
212  for motor in self.testWindow.dictMot:
213  value = 100 * (i+1)
214  valueList[i] = value
215  print(*valueList)
216  self.testWindow.dictMot[motor].setGoalPosition(value) # Every time a goal is set, a message is sent
217  expectedResult = self.testWindow.s.pack(b'a', *valueList, False, False, False, False, b'\0')
218  self.assertEqual(self.testWindow.msgDeque[-1], expectedResult)
219  i += 1
220 
221  # send status message
222  self.testWindow.sendMessage('s')
223  expectedResult = self.testWindow.s.pack(b's', *valueList, False, False, False, False, b'\0')
224  self.assertEqual(self.testWindow.msgDeque[-1], expectedResult)
225 
226  # send calibration message
227  self.testWindow.sendMessage('c')
228  expectedResult = self.testWindow.s.pack(b'c', *valueList, False, False, False, False, b'\0')
229  self.assertEqual(self.testWindow.msgDeque[-1], expectedResult)
230 
232  dummyPortsList = ["COM1", "COM2"]
233  self.testWindow.ports_list = dummyPortsList
234  self.testWindow.ui.portselection = QComboBox()
235  self.testWindow.populatePortsList()
236  AllItems = [self.testWindow.ui.portselection.itemText(i) for i in range(self.testWindow.ui.portselection.count())]
237  self.assertEqual(dummyPortsList, AllItems)
238 
239 
240 class TestMessageReception(unittest.TestCase):
241  def setUp(self):
242  self.testWindow = RoboAide.MainWindow(app)
243  self.testWindow.serialConnected = True
244  self.testWindow.comm = DummyComm()
245  self.testWindow.msgReception.start()
246 
247  def testRun(self):
248  """
249  Test for reading incoming message and updating the motors' current posisition
250  """
251  self.motorValues = [100, 200, 300, 400, 500, 600]
252  message = self.testWindow.s.pack(b'a', *self.motorValues, False, False, False, False, b'\0')
253  self.testWindow.comm.loadMessage(message)
254  time.sleep(1)
255  i = 0
256  for motor in self.testWindow.dictMot:
257  self.assertEqual(self.testWindow.dictMot[motor].getCurrentPosition(), self.motorValues[i])
258  i += 1
259 
260  def tearDown(self):
261  self.testWindow.msgReception.stop()
262  while self.testWindow.msgReception.isRunning(): # Make sure the thread has exited before continuing tests
263  pass
264 
265 class TestMessageTransmission(unittest.TestCase):
266  def setUp(self):
267  self.testWindow = RoboAide.MainWindow(app)
268  self.testWindow.serialConnected = True
269  self.testWindow.comm = DummyComm()
270  self.testWindow.msgTransmission.start()
271 
272  def testRun(self):
273  # Add a message to the msgDeque
274  motorValues = [100, 200, 300, 400, 500, 600]
275  message = self.testWindow.s.pack(b'a', *motorValues, False, False, False, False, b'\0')
276  self.testWindow.msgDeque.append(message)
277  time.sleep(1)
278  self.assertEqual(self.testWindow.comm.lastSentMessage, message)
279 
280  def tearDown(self):
281  self.testWindow.msgTransmission.stop()
282  while self.testWindow.msgTransmission.isRunning(): # Make sure the thread has exited before continuing tests
283  pass
284 
285 
286 class TestDrawers(unittest.TestCase):
287  def setUp(self):
288  self.testWindow = RoboAide.MainWindow(app)
289  self.testDrawer = Drawer(self.testWindow, "test")
290 
291  def testOpen(self):
292  self.testDrawer.open()
293  self.assertEqual(self.testDrawer.state, True)
294 
295  def testClose(self):
296  self.testDrawer.close()
297  self.assertEqual(self.testDrawer.state, False)
298 
299  def testSetState(self):
300  self.testDrawer.setState(True)
301  self.assertEqual(self.testDrawer.state, True)
302  self.testDrawer.setState(False)
303  self.assertEqual(self.testDrawer.state, False)
304 
305  def testGetState(self):
306  self.testDrawer.setState(True)
307  self.assertEqual(self.testDrawer.getState(), True)
308  self.testDrawer.setState(False)
309  self.assertEqual(self.testDrawer.getState(), False)
310 
311 
312 class DummyComm:
313  def __init__(self, message=""):
314  self.message = message
315  self.lastSentMessage = None
316 
317  def loadMessage(self, message):
318  self.message = message
319 
320  def read(self, messageSize):
321  timeout = time.time() + 0.1
322  while len(self.message) != messageSize and time.time() < timeout:
323  pass
324  tempMsg = self.message
325  self.message = ""
326  return tempMsg
327 
328  def write(self, message):
329  self.lastSentMessage = message
330 
331  def close(self):
332  pass
333 
334 
335 if __name__ == '__main__':
336  unittest.main()
def write(self, message)
Definition: test_ui.py:328
def test_set_status(self)
Definition: test_ui.py:51
def test_getNumberOfMoves(self)
Definition: test_ui.py:76
def test_wrong_motor_name(self)
Definition: test_ui.py:34
def loadMessage(self, message)
Definition: test_ui.py:317
def test_set_position(self)
Definition: test_ui.py:27
def test_deleteMove(self)
Definition: test_ui.py:88
def read(self, messageSize)
Definition: test_ui.py:320
def test_get_name(self)
Definition: test_ui.py:55
def test_get_position(self)
Definition: test_ui.py:23
def __init__(self, message="")
Definition: test_ui.py:313
def test_set_name(self)
Definition: test_ui.py:58
def test_is_enabled(self)
Definition: test_ui.py:48
def test_get_position(self)
Definition: test_ui.py:45
def test_populatePortsList(self)
Definition: test_ui.py:231