On executing this unittest getting
AttributeError: 'BaseUnit' object has no attribute 'driver'
import unittest
import redis
from selenium import webdriver
redis = redis.Redis(host='abc', port='123')
keys = redis.keys('*')
raw_baseunit = redis.get('test:baseunit')`enter code here`
class BaseUnit(unittest.TestCase):
def setup(self):
self.driver = webdriver.PhantomJS()
def test(self):
self.driver.get("myurl")
self.driver.find_element_by_id('username').send_keys("ngeo_pur1")
self.driver.find_element_by_id('password').send_keys("anything")
self.driver.find_element_by_xpath('html/body/div[1]/div[3]/div/section/div/form/ul/li[5]/div[2]/div/input').click()
self.driver.get("url")
self.driver.find_element_by_partial_link_text("18757424").click()
self.driver.find_element_by_xpath(".//*[#id='tabs']/nav/ul/li[2]/a/i").click()
Actual = self.driver.find_element_by_xpath(".//*[#id='subcat_baseModelSection.baseModelChoice']/div/div[1]").text
keys = redis.keys('*')
raw_baseunit = redis.get('test:baseUnit')
print "Actual Base Unit=",Actual
print "Expected Base Unit=",raw_baseunit
self.assetEquals(raw_baseunit,Actual)
def teardown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()
Tried changing the class name 'BaseUnit' as well
Try modifying the setup class's name to this. I just read the doc and the setup class is written with the U in uppercase
def setUp(self):
self.driver = webdriver.PhantomJS()
The methods you want to override in unittest.TestCase are setUp and tearDown (note the capital "U" and "D"), not setup and teardown.
Your all-lowercase setup method doesn't get called before the test methods run (if it gets called at all), so the self.driver attribute doesn't exist when then test method tries to use it.
Related
I have a question. Is it possible to change the name test in output, using python unittests?
For example, my test:
from selenium import webdriver
import unittest
from data.readData import Data
from actions.actions import Actions
from pages.notificationsPage import NotificationsPage
class NotificationsTest(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome(executable_path=Data.driver)
cls.driver.implicitly_wait(10)
cls.driver.maximize_window()
def test_order_confirmation(self):
Actions.login(self, Data.email, Data.password)
driver = self.driver
driver.get(Data.website + "Admin/Configuration/Message")
notify = NotificationsPage(driver)
notify.order_confirmation()
#classmethod
def tearDownClass(cls):
cls.driver.close()
cls.driver.quit()
if __name__ == '__main__':
unittest.main()
And my output:
I want to change the marked one test name to own string here, in this output, and also in result file in res.xml (I think it is the same value).
Is it possible?
Yes, Just simply change the name of your tests method. Just Change:
def test_order_confirmation(self):
to
def whatever_you_want_to_call_your_test(self):
I am using sample code with unittest but I receive an error when I execute it -- 'str' object has no attribute 'get'.
I searched Google but did not get an answer.
from selenium import webdriver
import unittest
class google1search(unittest.TestCase):
driver = 'driver'
#classmethod
def setupClass(cls):
cls.driver = webdriver.Chrome(chrome_options=options)
cls.driver.implicitly_wait(10)
cls.driver.maximize_window()
def test_search_automationstepbystep(self):
self.driver.get("https://google.com")
self.driver.find_element_by_name("q").send_keys("Automation Step By step")
self.driver.find_element_by_name("btnk").click()
def test_search_naresh(self):
self.driver.get("https://google.com")
self.driver.find_element_by_name("q").send_keys("Naresh")
self.driver.find_element_by_name("btnk").click()
#classmethod
def teardownClass(cls):
cls.driver.close()
cls.driver.quit()
print("Test completed")
if __name__== "__main__":
unittest.main()
Supposed to execute 2 steps and give result pass.
In the above code :
There is no initialization of self.driver for
self.driver.get("https://google.com")
as the driver initiated is for
cls.driver = webdriver.Chrome(chrome_options=options)
please replace cls with self
I want to extend #sarthak response little bit. In the sample code methods setUpClass and tearDownClass are used. These methods are called to prepare test class and called only once before executing all test in your test class.
Which can work in your case because at the beginning of each test you're overwriting internal state of the driver object and your previous test execution shouldn't affect your next test result. In this case you need to modify your tests to use class object:
def test_search_automationstepbystep(self):
TestClass.driver.get("https://google.com")
TestClass.driver.find_element_by_name("q").send_keys("Automation Step By step")
TestClass.driver.find_element_by_name("btnk").click()
def test_search_naresh(self):
TestClass.driver.get("https://google.com")
TestClass.driver.find_element_by_name("q").send_keys("Naresh")
TestClass.driver.find_element_by_name("btnk").click()
Where TestClass is the name of your test class.
The other option is to use setUp and tearDown methods to initialize driver object before each test case:
def setUp(self):
self.driver = webdriver.Chrome(chrome_options=options)
self.driver.implicitly_wait(10)
self.driver.maximize_window()
def tearDown(self):
self.driver.close()
self.driver.quit()
print("Test completed")
Both setUp and tearDown methods accept instance of TestClass as self argument and your tests should work without any additional changes.
Note: Usually second option is preferable for unit testing, cause you don't need to make sure in every test that you overwrite driver internal state before using find_element_by_name. And in second option you can put self.driver.get("https://google.com") code into setUp method, cause it's going to be executed before each test case anyway.
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class CorrecaoEfetivaNota(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome('/Users/r13/dev/chromedriver')
def teste_login_avaliador(self):
driver = self.driver
driver.get("")
cpf = driver.find_element_by_xpath('//input[#placeholder="CPF"]')
cpf.send_keys("")
password = driver.find_element_by_xpath('//input[#placeholder="SENHA"]')
password.send_keys("")
login = driver.find_element_by_tag_name('button')
login.click()
driver.implicitly_wait(3)
def teste_buscar_mais_um(self):
driver = self.driver
buscar = driver.find_element_by_xpath("//section[1]/div/div/section[2]/div/div/div[1]/div/div[2]/button")
buscar.click()
def tearDown(self):
self.driver.close()
I'm trying to write this tests in Python, the first function is ok, but the second one inside the class is not being executed in the tests. How can I organize this?
While working with Python and unittest module with Selenium you have to consider a few facts as follows :
Indentation for class and test_method are different.
Instead of driver.close() always invoke driver.quit() within tearDown(){} method to close & destroy the WebDriver and Web Client instances gracefully.
If you are using unittest module you have to call the __main__.
Here is your own code with the required minor modifications which will execute the first method teste_login_avaliador() as well as the second method teste_buscar_mais_um() within the Class CorrecaoEfetivaNota():
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class CorrecaoEfetivaNota(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path=r'C:\WebDrivers\chromedriver.exe')
def teste_login_avaliador(self):
driver = self.driver
driver.get("http://d3dyod5mwyu6xk.cloudfront.net/")
cpf = driver.find_element_by_xpath('//input[#placeholder="CPF"]')
cpf.send_keys("27922797885")
password = driver.find_element_by_xpath('//input[#placeholder="SENHA"]')
password.send_keys("enccejaregular")
login = driver.find_element_by_tag_name('button')
login.click()
driver.implicitly_wait(3)
def teste_buscar_mais_um(self):
driver = self.driver
buscar = driver.find_element_by_xpath("//section[1]/div/div/section[2]/div/div/div[1]/div/div[2]/button")
buscar.click()
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
unittest.main()
Note: Though both the test_methods are being called still you will face the following exception:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//section[1]/div/div/section[2]/div/div/div[1]/div/div[2]/button"}
At the line:
buscar = driver.find_element_by_xpath("//section[1]/div/div/section[2]/div/div/div[1]/div/div[2]/button")
This exception can be solved easily following the actual Test Steps of your usecase and if required you can raise a new question/ticket.
You write that the first function is ok, which I assume must be the setUp() function you are referring to (provided that in your code you indented correctly).
As Andersson comments, your unittest methods needs to begin with "test_" not "teste_". Providing "test_" is your way of telling unittest that this method should be tested.
In your unittest you probably also want to test something such as self.assertEqual(1,1) otherwise your tests will pass no matter what.
Next time please provide us with a more thorough description of what is wrong. How did you make the call to unittest? What error is python giving you? What result did you expect? Etc. It makes solving your problem much faster.
I encourage you to make a simple test first and ensure that it runs:
import unittest
class TestingUnittest(unittest.TestCase):
def setUp(self):
print("SetUp called")
def tearDown(self):
print("tearDown called")
def test_Method(self):
print("Testing 1==1")
self.assertEqual(1,1)
Call this from your terminal:
>>>python -m unittest "name-of-test.py"
I have multiple tests inside one test case but I am noticing that it is only running the first test
import unittest
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support.ui import WebDriverWait
class Test(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.base_url = "http://www.example.com/"
def test_Google(self):
driver = self.driver
driver.implicitly_wait(10)
driver.get(self.base_url)
def fill_contact(self):
driver.find_element_by_xpath('//a[contains(.,"Contact")]').click()
driver.implicitly_wait(10)
driver.find_element_by_xpath('//input[#type="submit"][#value="Send"]').click()
# def tearDown(self):
# self.driver.quit()
if __name__ == "__main__":
unittest.main()
Whenever I run this it only runs
def test_Google(self)
and nothing after that. am I doing something wrong?
Methods must begin with 'test' to be automatically run.
Per the docs:
A testcase is created by subclassing unittest.TestCase. The three
individual tests are defined with methods whose names start with the
letters test. This naming convention informs the test runner about
which methods represent tests. (my emphasis)
The TestLoader is responsible for loading test and returning them wrapped in a TestSuite. It uses this method to identify tests:
class TestLoader(object):
testMethodPrefix = 'test'
def getTestCaseNames(self, testCaseClass):
"""Return a sorted sequence of method names found within testCaseClass
"""
def isTestMethod(attrname, testCaseClass=testCaseClass,
prefix=self.testMethodPrefix):
return attrname.startswith(prefix) and \
hasattr(getattr(testCaseClass, attrname), '__call__')
testFnNames = filter(isTestMethod, dir(testCaseClass))
...
Thus, the attrname.startswith(prefix) checks if the method name begins with 'test'.
As an alternative to what #unubtu noted:
you can use a nose test runner and mark a method with #istest decorator:
from nose.tools import istest
class Test(unittest.TestCase):
...
#istest
def fill_contact(self):
driver.find_element_by_xpath('//a[contains(.,"Contact")]').click()
driver.implicitly_wait(10)
driver.find_element_by_xpath('//input[#type="submit"][#value="Send"]').click()
Besides, here is a pretty good overview of the unittest test discovery:
How does Python's unittest module detect test cases?
I'm trying to retrieve the session id of a selenium webdriver session during the execution of a test as such:
import unittest
class MyTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
def testSomething(self):
"""selenium tests go here"""
self.driver.get('http://www.example.com')
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
suite = unittest.TestLoader().loadTestsFromTestCase(MyTest)
testResult = unittest.TextTestRunner(verbosity=2).run(suite)
session_id = ???
I know I could do self.driver.session_id side the setUp method. The problem is I need to get the session id outside of the class instance. Any ideas?
Probably, you can create property/function inside the class instance which could return you sessionID.