Saturday, May 2, 2015

Write UnitTests in Selenium using Python


Selenium does not provide any Test Framework/Tool. We can use Python's unittest module to write the tests. Let's see how automate the following test steps:

1. Open www.gmail.com
2. Asset if the page contains the Text "Sign in to continue to Gmail"

here is the HTML code, how it looks like:

<div class="banner">
<h1>One account. All of Google. </h1>
<h2 class="hidden-small"> Sign in to continue to Gmail </h2>
</div>

Code:

#!/bin/python
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

class GmailSignUpTest(unittest.TestCase):
    "Tests for Gmail SignUp page"
  def setUp(self):
    self.driver = webdriver.Firefox()
  def tearDown(self):
    self.driver.close()
  def test_open_gmail_application(self):
    driver = self.driver
    driver.get("https://www.gmail.com")
    banner = driver.find_element_by_css_selector(".banner h2")
    self.assertEqual('Sign in to continue to Gmail', banner.text)

  if __name__ == "__main__":
    unittest.main()

Walk through the example:

Find the Element:
First let us see how to find the element in the page. If you look at the HTML, the required text is in the <h2> tag, which is a descendant of <div> with class name "banner". Selenium provides various ways to find the element. We can find the element by tag "h2" or find the element by class "hidden-small". But, I am using the CSS selector ".banner h2" this equivalent to <div class="banner"><h2> </h2></div>.

The DOT preceding the class name "banner" indicates that it is a class name. class name followed by h2 means, h2 is child of the element with class name "banner"
banner = driver.find_element_by_css_selector(".banner h2")
Get the Element Text:
There are various ways to get the element text in selenium. One of which is using "element.text" which returns the inner text of an element.
banner.text

UnitTests:
The fist line "import unittest" loads the Python's Unit Test module. To start with unittests, create class that inherits unittest "Test Class". Test cases start with "test_". When unittest reads the line 'test_' it understood as a unit test case.
setUp:
setUp() is a special method which will be called before executing the test case. This is similar to "before" statement in JAVA

tearDown:
tearDown() is a special method which will be called after executing the test case, this is similar to "after" statement. Most of the time we place code to close the browser and database cleanup

Running the Unit Tests:
Finally, "unittest.main()" is the method used to execute the Unit Test.

To understand "__name__" and "__main__" let us see the what happens when we execute these programs
#module1.py
print "Module 1: __name__ = %s", __name

The output of the above program is 
Module 1: __name__ = __main__

Now, will write another program 'module2' and import 'module1'
#module2.py
import module1

The output of the above program is
Module 1: __name__ = module1

Python assigns module name to '__name__' when it is imported by some other program. And when the program is executed as a main it assigns '__main__' to '__name__'

The statement if __name__ == "__main__" is just to make ensure that the test are executed only when it is executed as a program, not when it is imported by other programmes.