Python unittest for paramiko ssh connection - python-3.x

I wrote some python code that works great, now I'm tasked with writing tests for that code.
My team uses mock and pytest, but I haven't really been able to copy-paste and modify something useful.
I just need a kick start, for example here is a part of my code:
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.connect(hostname='1.2.3.4', username='ubuntu')
Can someone help me write a simple unittest for this?
I understand that going forward I'd have to think about my code and write the tests as I go, but I've never done this before so I'm really just looking to get a practical start to get going.

Unit testing ensures the code works per requirements. Get the requirements and write tests to check that the code works and show that the code throws appropriate errors. You can use RobotFramework or another test automation SW to automate the tests. Some questions you might ask yourself are listed below:
ssh = paramiko.SSHClient()
Does paramiko.SSHClient exist?
is it working?
what if it fails?
do you get an error or does the SW hang?
ssh.load_system_host_keys()
Can you load the system keys?
How can you verify this?
ssh.connect(hostname='1.2.3.4', username='ubuntu')
How can you prove the connection exists?
What happens if you try to connect to another host?
Do you get an error message?
Can you logon with username 'ubuntu'?
What if you try another username?
Does the connection fail?
Do you get a generic error so you don't give crackers clues about your security?
Proof of unit testing is usually a screen capture, log entry, or some documentation showing you got the result you expected when you ran the test. Hope this helps.

you can use unit test module like below
import unittest
import paramiko
class SimpleWidgetTestCase(unittest.TestCase): #This class inherits unittest.TestCase
#setup will run first
def setUp(self):
self.ssh = paramiko.SSHClient()
self.ssh.load_system_host_keys()
self.ssh.connect(hostname='1.2.3.4', username='ubuntu')
#Your test cases goes here with 'test' prefix
def test_split(self):
#your code here
pass
#this will run after the test cases
def tearDown(self):
#your code to clean or close the connection
pass
if __name__ == '__main__':
unittest.main()
detailed information about how to use unittest can be found here https://docs.python.org/2/library/unittest.html
one suggestion: robotframework is better option to design test cases in comparison to unit test, so until unless its not compulsory , you can invest your time in Robotframework

Related

Jupyter notebook python library testbook not giving any results

Here's my jupyter notebook's cell 1 (notebook is called tested.ipynb)
def func(a,b):
return a+b
Here's the testbook testing python code (tester.py):
import testbook
#testbook.testbook('tested.ipynb',execute=True)
def test_func(tb):
func=tb.ref("func")
assert func(1,2)==0
I then run the following command from terminal:
python tester.py
It should fail the unit test. But I'm not getting any output at all. No failures, no messages. How do I make the failure appear?
That's because you still need to use pytest, or another unit testing library, to run your tests. Note under 'Features' it says:
"Works with any unit testing library - unittest, pytest or nose" -SOURCE
Testbook just makes writing the unit tests easier. See here under 'Unit testing with testbook' for an example of the process of using testbook in your toolchain with pytest, although bear in mind a lot of the syntax doesn't match the the current documentation. And so instead of running python tester.py from the terminal, run the following command from terminal if you've installed pytest:
pytest tester.py
One thing I note, is that your import and decorator lines don't match the current documentation. Nevertheless, your code works when using pytest tester.py. However, it may be best to adopt the current best practices illustrated in the documentation to keep your code more robust as development continues.

Testing Flask microservices using unittest module

I have developed a very basic microservice using Flask framework.
A method in the application looks like this
#app.route('/add, methods=['POST'])
def add_info():
final = []
try:
info_obj.append(json.loads(request.data))
...
return jsonify(final)
Now I am attempting to write Unittest for this method and other method in this microservice. I am using import unittest to write my test.
Now here I am confused is how can I write tests to test the functionality of these http functions, which don't take regular argument of return regular results but rather fetch arguments from request data and return json based on that.
Is my approach correct? and if yes how can I test Microservices-like functionality using unittest module?
If you absolutely want unittesting, follow Patrick's guide here. But I suggest using PyTest. It's a breeze to get started. First you need a conftest.py. Then add your testfiles named test_... .py . The where your conftest is do $ pytest
Patrick has yet another PyTest + Flask guide here. You can view a demo of a conftest in a project here on how to set up db etc and a test file here

Running console window in background for GUI using tkinter on Windows 10

So I have this GUI that I made with tkinter and everything works well. What it does is connects to servers and sends commands for both Linux or Windows. I went ahead and used pyinstaller to create a windowed GUI without console and when I try to uses a specific function for sending Windows commands it will fail. If I create the GUI with a console that pops up before the GUI, it works like a charm. What I'm trying to figure out is how to get my GUI to work with the console being invisible to the user.
The part of my code that has the issue revolves around subprocess. To spare you all from the 400+ lines of code I wrote, I'm providing the specific code that has issues. Here is the snippet:
def rcmd_in(server):
import subprocess as sp
for i in command_list:
result = sp.run(['C:/"Path to executable"/rcmd.exe', '\\\\' + server, i],
universal_newlines=True, stdout=sp.PIPE, stderr=sp.STDOUT)
print(result.stdout)
The argument 'server' is passed from another function that calls to 'rcmd_in' and 'command_list' is a mutable list created in the root of the code, accessible for all functions.
Now, I have done my due diligence. I scoured multiple searches and came up with an edit to my code that makes an attempt to run my code with that console invisible, found using info from this link: recipe-subprocess. Here is what the edit looks like:
def rcmd_in(server):
import subprocess as sp
import os, os.path
si = sp.STARTUPINFO()
si.dwFlags |= sp.STARTF_USESHOWWINDOW
for i in command_list:
result = sp.run(['C:/"Path to executable"/rcmd.exe', '\\\\' + server, i],
universal_newlines=True, stdin=sp.PIPE, stdout=sp.PIPE,
stderr=sp.STDOUT, startupinfo=si, env=os.environ)
print(result.stdout)
The the problem I have now is when it runs an error of "Error:8 - Internal error -109" pops up. Let me add I tried using functions 'call()', 'Popen()', and others but only 'run()' seems to work.
I've reached a point where my brain hurts and I can use some help. Any suggestions? As always I am forever great full for anyone's help. Thanks in advance!
I figured it out and it only took me 5 days! :D
Looks like the reason the function would fail falls on how Windows handles stdin. I found a post that helped me edit my code to work with pyinstaller -w (--noconsole). Here is the updated code:
def rcmd_in(server):
import subprocess as sp
si = sp.STARTUPINFO()
si.dwFlags |= sp.STARTF_USESHOWWINDOW
for i in command_list:
result = sp.Popen(['C:/"Path to executable"/rcmd.exe', '\\\\' + server, i],
universal_newlines=True, stdin=sp.PIPE, stdout=sp.PIPE,
stderr=sp.PIPE, startupinfo=si)
print(result.stdout.read())
Note the change of functions 'run()' to 'Popen()'. The 'run()' function will not work with the print statement at the end. Also, for those of you who are curious the 'si' variable I created is preventing 'subprocess' from opening a console when being ran while using a GUI. I hope this will become useful to someone struggling with this. Cheers

Message: Tried to run command without establishing a connection

New to this, apologies for the novice question.
Trying to run a script using Python, Selenium and the unittest module. Have the typical setUp(), test_1, test_2, tearDown() method structure. Since I've added in more than one test, I get the following error:
selenium.common.exceptions.InvalidSessionIdException: Message: Tried to run command without establishing a connection
How can I resolve this?
I have looked into similar problems people have been facing with this issue, but in almost all cases the issue is not related to anything I am encountering (cronjobs for example)
My program looks like this...
class MyTest(unittest.TestCase):
#classmethod
def setUpClass(cls):
#my setup code here...
cls.driver = webdriver.Firefox(executable_path='my_gecko_driver')
cls.driver.get('www.my_url.com')
cls.driver...... # various other tasks
def test_1(self):
# my test code here....
foo = self.driver.find_element_by_xpath('/button_elem/')
foo.click()
# etc etc....
def test_2(self):
# my test code here....
bar = self.driver.find_element_by_xpath('/button_elem/')
bar.click()
# etc etc....
#classmethod
def tearDown(cls):
print('Entered tearDown function.')
# close the browser window
cls.driver.close()
if __name__ == '__main__':
unittest.main()
Before I added the second test, the test ran successfully.
Now I am getting the error:
selenium.common.exceptions.InvalidSessionIdException: Message: Tried to run command without establishing a connection
I suspect this is to do with the tearDown method perhaps not working correctly? However I thought this method was called at the end of every test_x upon finishing.
I have also noticed that Pycharm is highlighting 'driver' in the line 'cls.driver.close()' which I am also not too sure about. It says unresolved attribute reference' however is this not created in the setUp() method?
Try switching explicitly between tabs before closing them.
main_page = driver.window_handles[0]
driver.switch_to.window(main_page)
this is because multiple browser sessions are opened at your machine.
if you are on linux run the command
killall firefox
and try to run your script again. This should fix error for you.

Threading error in my python script

I don't understand why I get this threading error by just using the threading module. It works fine without the threading module.
I searched on internet, but I don't get the appropriate answer.
Add the following line before the try statement:
connSkt = None
Also modify the close part:
if connSkt is not None:
connSkt.close()

Resources