Can you use mock_open to simulate serial connections?
Morning folks,
I'm trying to get a few unit tests going in Python to confirm my code is working, but I'm having a real hard time getting a Mock anything to fit into my test cases. I'm new to Python unit testing, so this has been a trying week thus far.
The summary of the program is I'm attempting to do serial control of a commercial monitor I got my hands on and I thought I'd use it as a chance to finally use Python for something rather than just falling back on one of the other languages I know. I've got pyserial going, but before I start shoving a ton of commands out to the TV I'd like to learn the unittest part so I can write for my expected outputs and inputs.
I've tried using a library called dummyserial, but it didn't seem to be recognising the output I was sending. I thought I'd give mock_open a try as I've seen it works like a standard IO as well, but it just isn't picking up on the calls either. Samples of the code involved:
def testSendCmd(self):
powerCheck = '01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8')
read_text = 'Stuffr'
mo = mock_open(read_data=read_text)
mo.in_waiting = len(read_text)
with patch('__main__.open', mo):
with open('./serial', 'a+b') as com:
tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
com.write(b'some junk')
print(mo.mock_calls)
mo().write.assert_called_with('01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8'))
And in the SharpTV class, the function in question:
def sendCmd(self, type, msg):
sent = self.com.write('01:>4r'.format(type,msg).encode('utf-8'))
print('01:>4r'.format(type,msg).encode('utf-8'))
Obviously, I'm attempting to control a Sharp TV. I know the commands are correct, that isn't the issue. The issue is just the testing. According to documentation on the mock_open page, calling mo.mock_calls should return some data that a call was made, but I'm getting just an empty set of 's even in spite of the blatantly wrong com.write(b'some junk'), and mo().write.assert_called_with(...) is returning with an assert error because it isn't detecting the write from within sendCmd. What's really bothering me is I can do the examples from the mock_open section in interactive mode and it works as expected.
I'm missing something, I just don't know what. I'd like help getting either dummyserial working, or mock_open.
python python-3.x python-unittest pyserial
add a comment |
Morning folks,
I'm trying to get a few unit tests going in Python to confirm my code is working, but I'm having a real hard time getting a Mock anything to fit into my test cases. I'm new to Python unit testing, so this has been a trying week thus far.
The summary of the program is I'm attempting to do serial control of a commercial monitor I got my hands on and I thought I'd use it as a chance to finally use Python for something rather than just falling back on one of the other languages I know. I've got pyserial going, but before I start shoving a ton of commands out to the TV I'd like to learn the unittest part so I can write for my expected outputs and inputs.
I've tried using a library called dummyserial, but it didn't seem to be recognising the output I was sending. I thought I'd give mock_open a try as I've seen it works like a standard IO as well, but it just isn't picking up on the calls either. Samples of the code involved:
def testSendCmd(self):
powerCheck = '01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8')
read_text = 'Stuffr'
mo = mock_open(read_data=read_text)
mo.in_waiting = len(read_text)
with patch('__main__.open', mo):
with open('./serial', 'a+b') as com:
tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
com.write(b'some junk')
print(mo.mock_calls)
mo().write.assert_called_with('01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8'))
And in the SharpTV class, the function in question:
def sendCmd(self, type, msg):
sent = self.com.write('01:>4r'.format(type,msg).encode('utf-8'))
print('01:>4r'.format(type,msg).encode('utf-8'))
Obviously, I'm attempting to control a Sharp TV. I know the commands are correct, that isn't the issue. The issue is just the testing. According to documentation on the mock_open page, calling mo.mock_calls should return some data that a call was made, but I'm getting just an empty set of 's even in spite of the blatantly wrong com.write(b'some junk'), and mo().write.assert_called_with(...) is returning with an assert error because it isn't detecting the write from within sendCmd. What's really bothering me is I can do the examples from the mock_open section in interactive mode and it works as expected.
I'm missing something, I just don't know what. I'd like help getting either dummyserial working, or mock_open.
python python-3.x python-unittest pyserial
What's the type ofself.com? Whatever type that is, that's the type you need to patch out.
– Matt Messersmith
Nov 15 '18 at 21:35
It's technically a serial.Serial() instance (pyserial), but besides in_waiting there's not a lot of difference between a read() on pyserial and a read() on a standard open(). At least not how I'm using it. Changing out the patch, I've got mostly the same code except the following changes:mo = mock_opening(read_data=read_text)with patch('serial.Serial', mo):with serial.Serial() as com:tv = SharpTV(com=com...)
– Feynt
Nov 16 '18 at 13:10
The problem is that you're patching out the builtinopen, which may or may not be what you need to be mocking. Why not just patch thecomobject and be done with it? Furthermore, that function is so simple that it hardly warrants a test...especially if you're going to mock out the write operation...
– Matt Messersmith
Nov 16 '18 at 14:12
Digging into dummyserial I found that it's decoding my input back into a string and checking against my dictionary for an actual string versus a byte encoded string. I've adjusted that and it seems like it's working for me now. I have more tests to do beyond this simple sendCmd, but I wanted to make sure I could at least get this working before moving onto (slightly) harder things like testing TV status codes loaded from a config file.
– Feynt
Nov 16 '18 at 14:18
add a comment |
Morning folks,
I'm trying to get a few unit tests going in Python to confirm my code is working, but I'm having a real hard time getting a Mock anything to fit into my test cases. I'm new to Python unit testing, so this has been a trying week thus far.
The summary of the program is I'm attempting to do serial control of a commercial monitor I got my hands on and I thought I'd use it as a chance to finally use Python for something rather than just falling back on one of the other languages I know. I've got pyserial going, but before I start shoving a ton of commands out to the TV I'd like to learn the unittest part so I can write for my expected outputs and inputs.
I've tried using a library called dummyserial, but it didn't seem to be recognising the output I was sending. I thought I'd give mock_open a try as I've seen it works like a standard IO as well, but it just isn't picking up on the calls either. Samples of the code involved:
def testSendCmd(self):
powerCheck = '01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8')
read_text = 'Stuffr'
mo = mock_open(read_data=read_text)
mo.in_waiting = len(read_text)
with patch('__main__.open', mo):
with open('./serial', 'a+b') as com:
tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
com.write(b'some junk')
print(mo.mock_calls)
mo().write.assert_called_with('01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8'))
And in the SharpTV class, the function in question:
def sendCmd(self, type, msg):
sent = self.com.write('01:>4r'.format(type,msg).encode('utf-8'))
print('01:>4r'.format(type,msg).encode('utf-8'))
Obviously, I'm attempting to control a Sharp TV. I know the commands are correct, that isn't the issue. The issue is just the testing. According to documentation on the mock_open page, calling mo.mock_calls should return some data that a call was made, but I'm getting just an empty set of 's even in spite of the blatantly wrong com.write(b'some junk'), and mo().write.assert_called_with(...) is returning with an assert error because it isn't detecting the write from within sendCmd. What's really bothering me is I can do the examples from the mock_open section in interactive mode and it works as expected.
I'm missing something, I just don't know what. I'd like help getting either dummyserial working, or mock_open.
python python-3.x python-unittest pyserial
Morning folks,
I'm trying to get a few unit tests going in Python to confirm my code is working, but I'm having a real hard time getting a Mock anything to fit into my test cases. I'm new to Python unit testing, so this has been a trying week thus far.
The summary of the program is I'm attempting to do serial control of a commercial monitor I got my hands on and I thought I'd use it as a chance to finally use Python for something rather than just falling back on one of the other languages I know. I've got pyserial going, but before I start shoving a ton of commands out to the TV I'd like to learn the unittest part so I can write for my expected outputs and inputs.
I've tried using a library called dummyserial, but it didn't seem to be recognising the output I was sending. I thought I'd give mock_open a try as I've seen it works like a standard IO as well, but it just isn't picking up on the calls either. Samples of the code involved:
def testSendCmd(self):
powerCheck = '01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8')
read_text = 'Stuffr'
mo = mock_open(read_data=read_text)
mo.in_waiting = len(read_text)
with patch('__main__.open', mo):
with open('./serial', 'a+b') as com:
tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
com.write(b'some junk')
print(mo.mock_calls)
mo().write.assert_called_with('01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK']).encode('utf-8'))
And in the SharpTV class, the function in question:
def sendCmd(self, type, msg):
sent = self.com.write('01:>4r'.format(type,msg).encode('utf-8'))
print('01:>4r'.format(type,msg).encode('utf-8'))
Obviously, I'm attempting to control a Sharp TV. I know the commands are correct, that isn't the issue. The issue is just the testing. According to documentation on the mock_open page, calling mo.mock_calls should return some data that a call was made, but I'm getting just an empty set of 's even in spite of the blatantly wrong com.write(b'some junk'), and mo().write.assert_called_with(...) is returning with an assert error because it isn't detecting the write from within sendCmd. What's really bothering me is I can do the examples from the mock_open section in interactive mode and it works as expected.
I'm missing something, I just don't know what. I'd like help getting either dummyserial working, or mock_open.
python python-3.x python-unittest pyserial
python python-3.x python-unittest pyserial
edited Nov 15 '18 at 20:31
Torxed
13.8k105790
13.8k105790
asked Nov 15 '18 at 20:27
FeyntFeynt
1316
1316
What's the type ofself.com? Whatever type that is, that's the type you need to patch out.
– Matt Messersmith
Nov 15 '18 at 21:35
It's technically a serial.Serial() instance (pyserial), but besides in_waiting there's not a lot of difference between a read() on pyserial and a read() on a standard open(). At least not how I'm using it. Changing out the patch, I've got mostly the same code except the following changes:mo = mock_opening(read_data=read_text)with patch('serial.Serial', mo):with serial.Serial() as com:tv = SharpTV(com=com...)
– Feynt
Nov 16 '18 at 13:10
The problem is that you're patching out the builtinopen, which may or may not be what you need to be mocking. Why not just patch thecomobject and be done with it? Furthermore, that function is so simple that it hardly warrants a test...especially if you're going to mock out the write operation...
– Matt Messersmith
Nov 16 '18 at 14:12
Digging into dummyserial I found that it's decoding my input back into a string and checking against my dictionary for an actual string versus a byte encoded string. I've adjusted that and it seems like it's working for me now. I have more tests to do beyond this simple sendCmd, but I wanted to make sure I could at least get this working before moving onto (slightly) harder things like testing TV status codes loaded from a config file.
– Feynt
Nov 16 '18 at 14:18
add a comment |
What's the type ofself.com? Whatever type that is, that's the type you need to patch out.
– Matt Messersmith
Nov 15 '18 at 21:35
It's technically a serial.Serial() instance (pyserial), but besides in_waiting there's not a lot of difference between a read() on pyserial and a read() on a standard open(). At least not how I'm using it. Changing out the patch, I've got mostly the same code except the following changes:mo = mock_opening(read_data=read_text)with patch('serial.Serial', mo):with serial.Serial() as com:tv = SharpTV(com=com...)
– Feynt
Nov 16 '18 at 13:10
The problem is that you're patching out the builtinopen, which may or may not be what you need to be mocking. Why not just patch thecomobject and be done with it? Furthermore, that function is so simple that it hardly warrants a test...especially if you're going to mock out the write operation...
– Matt Messersmith
Nov 16 '18 at 14:12
Digging into dummyserial I found that it's decoding my input back into a string and checking against my dictionary for an actual string versus a byte encoded string. I've adjusted that and it seems like it's working for me now. I have more tests to do beyond this simple sendCmd, but I wanted to make sure I could at least get this working before moving onto (slightly) harder things like testing TV status codes loaded from a config file.
– Feynt
Nov 16 '18 at 14:18
What's the type of
self.com? Whatever type that is, that's the type you need to patch out.– Matt Messersmith
Nov 15 '18 at 21:35
What's the type of
self.com? Whatever type that is, that's the type you need to patch out.– Matt Messersmith
Nov 15 '18 at 21:35
It's technically a serial.Serial() instance (pyserial), but besides in_waiting there's not a lot of difference between a read() on pyserial and a read() on a standard open(). At least not how I'm using it. Changing out the patch, I've got mostly the same code except the following changes:
mo = mock_opening(read_data=read_text) with patch('serial.Serial', mo): with serial.Serial() as com: tv = SharpTV(com=com...)– Feynt
Nov 16 '18 at 13:10
It's technically a serial.Serial() instance (pyserial), but besides in_waiting there's not a lot of difference between a read() on pyserial and a read() on a standard open(). At least not how I'm using it. Changing out the patch, I've got mostly the same code except the following changes:
mo = mock_opening(read_data=read_text) with patch('serial.Serial', mo): with serial.Serial() as com: tv = SharpTV(com=com...)– Feynt
Nov 16 '18 at 13:10
The problem is that you're patching out the builtin
open, which may or may not be what you need to be mocking. Why not just patch the com object and be done with it? Furthermore, that function is so simple that it hardly warrants a test...especially if you're going to mock out the write operation...– Matt Messersmith
Nov 16 '18 at 14:12
The problem is that you're patching out the builtin
open, which may or may not be what you need to be mocking. Why not just patch the com object and be done with it? Furthermore, that function is so simple that it hardly warrants a test...especially if you're going to mock out the write operation...– Matt Messersmith
Nov 16 '18 at 14:12
Digging into dummyserial I found that it's decoding my input back into a string and checking against my dictionary for an actual string versus a byte encoded string. I've adjusted that and it seems like it's working for me now. I have more tests to do beyond this simple sendCmd, but I wanted to make sure I could at least get this working before moving onto (slightly) harder things like testing TV status codes loaded from a config file.
– Feynt
Nov 16 '18 at 14:18
Digging into dummyserial I found that it's decoding my input back into a string and checking against my dictionary for an actual string versus a byte encoded string. I've adjusted that and it seems like it's working for me now. I have more tests to do beyond this simple sendCmd, but I wanted to make sure I could at least get this working before moving onto (slightly) harder things like testing TV status codes loaded from a config file.
– Feynt
Nov 16 '18 at 14:18
add a comment |
1 Answer
1
active
oldest
votes
To answer one part of my question, I figured out the functionality of dummyserial. The following works now:
def testSendCmd(self):
powerCheck = '01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK'])
com = dummyserial.Serial(
port='COM1',
baudrate=9600,
ds_responses=powerCheck : powerCheck
)
tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
self.assertEqual(tv.recv(), powerCheck)
Previously I was encoding the dictionary values as utf-8. The dummyserial library decodes whatever you write(...) to it so it's a straight string vs. string comparison. It also encodes whatever you're read()ing as latin1 on the way back out.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53327415%2fcan-you-use-mock-open-to-simulate-serial-connections%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
To answer one part of my question, I figured out the functionality of dummyserial. The following works now:
def testSendCmd(self):
powerCheck = '01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK'])
com = dummyserial.Serial(
port='COM1',
baudrate=9600,
ds_responses=powerCheck : powerCheck
)
tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
self.assertEqual(tv.recv(), powerCheck)
Previously I was encoding the dictionary values as utf-8. The dummyserial library decodes whatever you write(...) to it so it's a straight string vs. string comparison. It also encodes whatever you're read()ing as latin1 on the way back out.
add a comment |
To answer one part of my question, I figured out the functionality of dummyserial. The following works now:
def testSendCmd(self):
powerCheck = '01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK'])
com = dummyserial.Serial(
port='COM1',
baudrate=9600,
ds_responses=powerCheck : powerCheck
)
tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
self.assertEqual(tv.recv(), powerCheck)
Previously I was encoding the dictionary values as utf-8. The dummyserial library decodes whatever you write(...) to it so it's a straight string vs. string comparison. It also encodes whatever you're read()ing as latin1 on the way back out.
add a comment |
To answer one part of my question, I figured out the functionality of dummyserial. The following works now:
def testSendCmd(self):
powerCheck = '01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK'])
com = dummyserial.Serial(
port='COM1',
baudrate=9600,
ds_responses=powerCheck : powerCheck
)
tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
self.assertEqual(tv.recv(), powerCheck)
Previously I was encoding the dictionary values as utf-8. The dummyserial library decodes whatever you write(...) to it so it's a straight string vs. string comparison. It also encodes whatever you're read()ing as latin1 on the way back out.
To answer one part of my question, I figured out the functionality of dummyserial. The following works now:
def testSendCmd(self):
powerCheck = '01:>4r'.format(SharpCodes['POWER'], SharpCodes['CHECK'])
com = dummyserial.Serial(
port='COM1',
baudrate=9600,
ds_responses=powerCheck : powerCheck
)
tv = SharpTV(com=com, TVID=999, tvInput = 'DVI')
tv.sendCmd(SharpCodes['POWER'], SharpCodes['CHECK'])
self.assertEqual(tv.recv(), powerCheck)
Previously I was encoding the dictionary values as utf-8. The dummyserial library decodes whatever you write(...) to it so it's a straight string vs. string comparison. It also encodes whatever you're read()ing as latin1 on the way back out.
answered Nov 16 '18 at 14:26
FeyntFeynt
1316
1316
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53327415%2fcan-you-use-mock-open-to-simulate-serial-connections%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
What's the type of
self.com? Whatever type that is, that's the type you need to patch out.– Matt Messersmith
Nov 15 '18 at 21:35
It's technically a serial.Serial() instance (pyserial), but besides in_waiting there's not a lot of difference between a read() on pyserial and a read() on a standard open(). At least not how I'm using it. Changing out the patch, I've got mostly the same code except the following changes:
mo = mock_opening(read_data=read_text)with patch('serial.Serial', mo):with serial.Serial() as com:tv = SharpTV(com=com...)– Feynt
Nov 16 '18 at 13:10
The problem is that you're patching out the builtin
open, which may or may not be what you need to be mocking. Why not just patch thecomobject and be done with it? Furthermore, that function is so simple that it hardly warrants a test...especially if you're going to mock out the write operation...– Matt Messersmith
Nov 16 '18 at 14:12
Digging into dummyserial I found that it's decoding my input back into a string and checking against my dictionary for an actual string versus a byte encoded string. I've adjusted that and it seems like it's working for me now. I have more tests to do beyond this simple sendCmd, but I wanted to make sure I could at least get this working before moving onto (slightly) harder things like testing TV status codes loaded from a config file.
– Feynt
Nov 16 '18 at 14:18