I am creating an automation framework from scratch using selenium with python and would really like some input and advice on the best way to do so.
So far I have the following but my test script will not run. Please help!
script.py
from selenium import webdriver
class WebDriver(object):
def __init__(self, driver=None):
"""
__init__ setup webdriver test script class
"""
self.driver = driver
def setup(self):
self.driver = webdriver.Chrome()
def teardown(self):
self.driver.quit()
test.py
import script
class Test(script.WebDriver):
def search(self):
self.driver.get("www.google.com")
self.driver.find_element_by_id("lst-ib").clear()
I'm assuming you are trying to run this with python unittest. If so, your class should inherit from unittest.TestCase in order to mark that it contains test cases:
class WebDriver(unittest.TestCase)
...
class Test(script.WebDriver)
And second missing piece is "boiler plate code to run the test suite" (see explanation here) in test.py:
if __name__ == "__main__":
test.main()
Related
I am trying to run Selenium test in Python on Linux Ubuntu environment.
Geckodriver is located in my project root folder.
I run the file named siteTest.py from PyCharm command line:
python3 siteTest.py
However, I do not see any output from Selenium.
The test worked before I divided it into setUp, test and tearDown and added self as a parameter.
Any suggestions what I am doing wrong?
Thanks in advance.
import os
import unittest
from selenium import webdriver
class siteTest:
def setUp(self):
ROOT_DIR = os.path.abspath(os.curdir)
self.driver = webdriver.Firefox(executable_path=ROOT_DIR + '/geckodriver')
def test(self):
driver = self.driver
driver.get('https://google.com/')
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
unittest.main()
Your program was near perfect. You just need to annotate the siteTest class as unittest.TestCase. So effectively, you need to rewrite the line:
class siteTest:
as:
class siteTest(unittest.TestCase):
You probably need to annotate your set up and tear down methods.
#classmethod
def setUp(self)
.
.
#classmethod
def tearDown(self)
.
.
Here, I have annotated as class method so it will run only once for the class.
Is there any proper way to using getting url in cmd as argument along testcases.py file?
I am running below commmand in cmd to run test cases of python file:
testcases.py "any url"
testcases.py have coding:
class JSAlertCheck(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome("E:\chromedriver.exe")
self.url = sys.argv[1]
def test_Case1(self):
driver = self.driver
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
unittest.main(sys.argv[1])
As per the discussion Python unittest passing arguments the Python Pundits seems to convey that:
Unit tests should be stand-alone which will have no dependencies outside of their setUp() and tearDown() methods. This is to make sure that each tests has minimal side-effects and reactions to the other test. Passing in a parameter defeats this property of unittest and thus makes them sort of invalid. Using a Test Configuration would have been the easiest way and more appropiate as a unittest should never rely on foreign data to perform the test.
If you still want to do so, here is one of the working solution:
Code Block:
from selenium import webdriver
import unittest
import sys
class MyTest(unittest.TestCase):
URL = "foo"
def setUp(self):
self.driver = webdriver.Chrome(executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver = self.driver
driver.get(self.URL)
def test_Case1(self):
driver = self.driver
print(driver.title)
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
if len(sys.argv) > 1:
MyTest.URL = sys.argv.pop()
unittest.main()
CLI Command:
python unittest_cmdline_urlASarguments.py http://www.python.org
Output:
C:\Users\AtechM_03\LearnAutmation\PythonProject\readthedocs>python unittest_cmdline_urlASarguments.py http://www.python.org
[4448:5632:0606/205445.017:ERROR:install_util.cc(589)] Unable to create registry key HKLM\SOFTWARE\Policies\Google\Chrome for reading result=2
DevTools listening on ws://127.0.0.1:5634/devtools/browser/40cc6c16-1e52-4f49-a54f-08fac3ff7abc
Welcome to Python.org
.
----------------------------------------------------------------------
Ran 1 test in 9.534s
OK
C:\Users\AtechM_03\LearnAutmation\PythonProject\readthedocs>
Commandline Snapshot:
I have a little issue with webdriver.My machine run windows 7 and successfuly install python and selenium webdriver.Here is the problem
When i run this file
from selenium import webdriver
import HTMLTestRunner
import unittest
class nexmo(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.get("http://wwww.facebook.com")
def test_login(self):
emailFieldId = "email"
el = self.driver.find_element_by_id(emailFieldId)
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()
The test give me
Ran 0
OK But the Firefox doesnt start and do the things i tell him.
When I run
from selenium import webdriver
self.driver = webdriver.Firefox()
self.driver.get("http://wwww.facebook.com")
emailFieldId = "email"
el = self.driver.find_element_by_id(emailFieldId)
self.driver.quit()
Everything is OK.The browser starts and find the element.
I took your code and copy/pasted it into my Eclipse and it ran fine.
By chance did you re-type this code into SO rather than copy paste? Is it possible that there is a typo in your "def test_login(self):" line such that unittest can't identify it as a test case? This is my best guess. Since unittest first checks to see if you have any unit tests (identified as a function with the pre-fix "test_". If and only if it finds a test case will it run setUp and tearDown.
Also, the point of unit testing is to actually test that you received a valid value. Can I recommend adding this to the end of "def test_login":
self.assertIsNotNone(el)
I am trying to run a selenium test and this seems nothing happening. I tested the following code to make sure the setting was working: the firefox browser loaded as it is expected.
In functional_tests.py
browser = webdriver.Firefox()
broswer.get('http://localhost:8000')
But when I changed it to as follows:
import unittest
from selenium import webdriver
class NewVistorTest(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
def tearDown(self):
self.browser.quit()
def test_can_open_browser(self):
self.browser.get('http://localhost:8000')
self.assertIn('Test', self.browser.title)
It was not opening the browser, nothing was happening. I ran this python functional_tests.py
What is the best way to organize unit tests and selenium tests. I'd like to run it by module name, not all in tests.py or test_abc.py, not by nose.
How do you expect it to run? Python won't automatically run tests, just because they're in a class. You need to add a couple more lines to the end of your file:
class NewVistorTest(unittest.TestCase):
...
if __name__ == '__main__':
unittest.main(warnings='ignore')
This conditional is how a Python script checks if it has been executed from the command line, rather than just imported by another script. We call unittest.main() to launch the unittest test runner, which will automatically find test and methods in the file and run them.
Without that block, as you've seen, nothing happens.
I'm creating a sample test using Selenium and the python bindings and running it with nose. I know I'm doing something wrong because the test opens two browsers (when setup is run, a Firefox window opens up and closes immediately, and then when the test runs driver.get, another window opens). I have the following project:
/test_project
/config
config.ini
/pages
__init__.py
test_page.py
/test_scripts
script.py
__init__.py
base.py
config_parser.py
config.ini:
[Selenium]
browser: firefox
base_url: http://www.google.com/
chromedriver_path:
base.py
from selenium import webdriver
from config_parser import Config
class TestCase(object):
def setup(self):
self.config = Config()
if self.config.read_config('Selenium', 'browser').lower() == 'firefox':
self.driver = webdriver.Firefox()
elif self.config.read_config('Selenium', 'browser').lower() == 'chrome':
self.driver = webdriver.Chrome(self.config.read_config('Selenium', 'chromedriver_path'))
def teardown(self):
self.driver.quit()
test_page.py
from config_parser import Config
class TestPage(object):
def __init__(self, driver):
self.driver = driver
self.config = Config()
def open(self):
self.driver.get(self.config.read_config('Selenium', 'base_url'))
import time
time.sleep(3)
script.py
from pages import test
from base import TestCase
class RandomTest(TestCase):
def test_foo(self):
x = test.TestPage(self.driver)
x.open()
assert 1 == 1
Can someone help me understand why two browser windows are opening and what I can do to correct this issue?
Thank you in advance.
This is because your base TestCase class is being recognized by nose test runner as a test too.
Mark it with #nottest decorator:
from selenium import webdriver
from config_parser import Config
from nose.tools import nottest
#nottest
class TestCase(object):
...