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.
Related
I've seen a couple questions similar to this, but they both appear to involve VBA and not Python.
This is a relatively recent error, so I suspect it might have something to do with the fact that I'm using Python 3.7 now.
Basically, using the Dispatch method from win32com.client, I am able to open a new Excel workbook and make my edits as I always have been. However, for some reason, I am unable to tell the application to quit successfully.
Used to be that I could write:
self.excel_app.Quit()
But now, I'm getting an AttributeError, of all things. Saying the Excel.Application does not have a Quit() attribute. Again, this is Python 3.7. What happened?
[EDIT]
Relevant code:
import sys
from win32com.client import Dispatch
#...
class X(object):
def __init__(self):
#...
self.excel_app = Dispatch("Excel.Application")
self.report_workbook = self.excel_app.Workbooks.Add()
#...
def close_excel(self):
try:
self.excel_app.Quit()
except Exception as ex:
sys.stdout.write("Could not quit application.\n-> ({}) {}\n".format(ex.__class__.__name__, ex))
self.excel_app = None
The exception printed to the terminal is:
Could not quit application.
(AttributeError) Excel.Application.Quit
Turns out that my error was coming from the fact that I was still using threading.Thread as the base class for the object trying to do this. Apparently it doesn't work so well with the Dispatch Excel objects anymore, and I'm trying to move away from Threads anyway.
I have a code that is architecturally close to posted below (unfortunately i can't post full version cause it's proprietary). I have an self-updating executable and i'm trying to test this feature. We assume that full path to this file will be in A.some_path after executing input. My problem is that assertion failed, because on second call os.stat still returning the previous file stats (i suppose it thinks that nothing could changed so it's unnecessary). I have tried to launch this manually and self-updating works completely fine and the file is really removing and recreating with stats changing. Is there any guaranteed way to force os.stat re-read file stats by the same path, or alternative option to make it works (except recreating an A object)?
from pathlib import Path
import unittest
import os
class A:
some_path = Path()
def __init__(self, _some_path):
self.some_path = Path(_some_path)
def get_path(self):
return self.some_path
class TestKit(unittest.TestCase):
def setUp(self):
pass
def check_body(self, a):
some_path = a.get_path()
modification_time = os.stat(some_path).st_mtime
# Launching self-updating executable
self.assertTrue(modification_time < os.stat(some_path).st_mtime)
def check(self):
a = A(input('Enter the file path\n'))
self.check_body(a)
def Tests():
suite = unittest.TestSuite()
suite.addTest(TestKit('check'))
return suite
def main():
tests_suite = Tests()
unittest.TextTestRunner().run(tests_suite)
if __name__ == "__main__":
main()
I have found the origins of the problem: i've tried to launch self-updating via os.system which wait till the process done. But first: during the self-updating we launch several detached proccesses and actually should wait unitl all them have ended, and the second: even the signal that the proccess ends doesn't mean that OS really completely realease the file, and looks like on assertTrue we are not yet done with all our routines. For my task i simply used sleep, but normal solution should analyze the existing proccesses in the system and wait for them to finish, or at least there should be several attempts with awaiting.
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
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()
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