How to use multiple modules

This is the place for queries that don't fit in any of the other categories.

How to use multiple modules

Postby dragonix » Wed May 29, 2013 8:30 am

Hi all

I'm new to this forum and quiet new to Python.
Probably some of you will have heard of Selenium, well this is a automation tool for webUI testing. At least, that is how I use it ;)
Now, I'm trying to convert my HTML test cases to python.
What I try to do is, is to have one main file (where is described which test scripts to use) and different modules that describes the steps taken.
In the test scripts, I also do some checks like check if a specific element is present.

Here is how it is written at the moment
Main file:
Code: Select all
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re
from login import *

class OpenBms(unittest.TestCase):
   
    def setUp(self):
        print "setup"
        self.driver = webdriver.Chrome()
        self.base_url = "http://ipaddress/Login.aspx"
        self.verificationErrors = []
        self.accept_next_alert = "true"
        print "end setup"
       
    def test_login(self):
        print "start test_login"
        print "call login_bms from login.py"
        login_bms(self)
        print "end of calling"
                       
    def tearDown(self):
        print "Demolish"
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

#       
if __name__ == '__main__':
    unittest.main(verbosity=2)


So as you can see, the other module is called 'login' and I call the 'login_bms' definition.
This is written like:
Code: Select all
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re

def login_bms(self):
    print "start of login_bms call"
    chrome = self.driver
    chrome.maximize_window()
    chrome.get(self.base_url)
    chrome.find_element_by_id("ctl00_GuiContent_Login1_UserName").clear()
    chrome.find_element_by_id("ctl00_GuiContent_Login1_UserName").send_keys("username")
    chrome.find_element_by_id("ctl00_GuiContent_Login1_Password").clear()
    chrome.find_element_by_id("ctl00_GuiContent_Login1_Password").send_keys("password")
    chrome.find_element_by_id("ctl00_GuiContent_Login1_LoginButton").click()
    time.sleep(60)
    print "end of clicking the login button"
    for i in range(120):
        print "inside for-lus"
        try:
            print "inside try"
            if self.is_element_present(By.ID, "ctl00_MainPageTitleContent_EditPageTitleControl_TitleLabel"): break
        except: pass
        print "sleeping time"
        time.sleep(1)
    else: self.fail("time out")

def is_element_present(self, how, what):
    print "within is_element_present"
    try: self.driver.find_element(by=how, value=what)
    except NoSuchElementException, e: return False
    return True

def close_alert_and_get_its_text(self):
    print "within close_alert"
    try:
        alert = self.driver.switch_to_alert()
        if self.accept_next_alert:
            alert.accept()
        else:
                alert.dismiss()
        return alert.text()
    finally: self.accept_next_alert = True
       
if __name__ == '__main__':
    unittest.main()


This is the logging I receive when executing the test case:
Code: Select all
Finding files... done.
Importing test modules ... done.

setup
end setup
start test_login
call login_bms from login.py
start of login_bms call
end of clicking the login button
inside for-lus
inside try
sleeping time
inside for-lus
inside try
sleeping time
inside for-lus
inside try
sleeping time
inside for-lus
inside try
sleeping time
inside for-lus
inside try
sleeping time
inside for-lus
inside try
sleeping time
inside for-lus
inside try
sleeping time
... a lot more of these small messages ...
Demolish
======================================================================
FAIL: test_login (main.OpenBms)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\eclipse\Workspace\Project_Selenium\src\main.py", line 30, in test_login
    login_bms(self)
  File "C:\eclipse\Workspace\Project_Selenium\src\login.py", line 53, in login_bms
    else: self.fail("time out")
AssertionError: time out

----------------------------------------------------------------------
Ran 1 test in 193.128s

FAILED (failures=1)


At the moment I'm a bit lost of why he doesn't want to go in the other function 'is_element_present' :(
Can someone help me out?

Thanks!

Dragonix
dragonix
 
Posts: 9
Joined: Wed May 29, 2013 8:21 am

Re: How to use multiple modules

Postby setrofim » Wed May 29, 2013 9:28 am

It's not executing is_element_present because you're not calling it from anywhere. Rather than trying to load tests from one module into another, just write a separate test case in each module and use something like nose or unittest2 to discover and run them all.
setrofim
 
Posts: 288
Joined: Mon Mar 04, 2013 7:52 pm

Re: How to use multiple modules

Postby dragonix » Wed May 29, 2013 10:26 am

I thought I was calling it in this part

Code: Select all
for i in range(120):
        print "inside for-lus"
        try:
            print "inside try"
///// this part /////
            if self.is_element_present(By.ID, "ctl00_MainPageTitleContent_EditPageTitleControl_TitleLabel"): break
//////////////////
        except: pass
        print "sleeping time"
        time.sleep(1)
    else: self.fail("time out")


Can you give me a small example perhaps of how you use nose or unittest2?
Do I need a specific version of Python?

I also want to reuse some testcases, like this login part I would like to reuse it in other 'test suites'
So I thought this was the best way to do it?
dragonix
 
Posts: 9
Joined: Wed May 29, 2013 8:21 am

Re: How to use multiple modules

Postby setrofim » Wed May 29, 2013 1:05 pm

dragonix wrote:I thought I was calling it in this part

Code: Select all
for i in range(120):
        print "inside for-lus"
        try:
            print "inside try"
///// this part /////
            if self.is_element_present(By.ID, "ctl00_MainPageTitleContent_EditPageTitleControl_TitleLabel"): break
//////////////////
        except: pass
        print "sleeping time"
        time.sleep(1)
    else: self.fail("time out")


No, is_element_present is not a member method of your TestCase; it's just a separate function. You cannot access it through self. That code will rase an exception (hat you are then ignorring -- which is a very bad habbit).

dragonix wrote:Can you give me a small example perhaps of how you use nose or unittest2?
Do I need a specific version of Python?

Any recent version of Python 2 should do. You can get it from PyPI, so just do a pip install. Haven't used unittest2 myself, I prefer nose for unit testing. Nose will auto discover all tests in files or directories that have "test" on a word boundary in their name. Nose recognises unittest TestCases, so you don't need to do anything special in your code to use it. Just run "nosetests" in your project directory once you've installed it.

dragonix wrote:I also want to reuse some testcases, like this login part I would like to reuse it in other 'test suites'
So I thought this was the best way to do it?

Since unit tests are meant to test detailed functionality and are specific to the code they are testing, they are generally not reusable across projects. If you have some common functionality that you want to reuse across multiple tests, split it off into a separate module that is then used within the test cases.
setrofim
 
Posts: 288
Joined: Mon Mar 04, 2013 7:52 pm

Re: How to use multiple modules

Postby dragonix » Thu May 30, 2013 8:32 am

Thanks for the help!

How should I do it then?
Using the code provided, what is the best way of getting it right?
dragonix
 
Posts: 9
Joined: Wed May 29, 2013 8:21 am

Re: How to use multiple modules

Postby setrofim » Thu May 30, 2013 12:08 pm

  • Keep all your tests inside a TestCase.
  • Tests that test the same class/aspect of your program and share setup and teardown code belong in the same TestCase.
  • How you organise you tests beyond that would depend on your project -- you can have multiple TestCases in the same file, or split them out (e.g. one file for each of your modules).
  • Any functionality that is generally reusable (e.g. setting stuff up with selenium) should not be in a TestCase and should reside in its own module (e.g. test_utils). You would then import it and call it in the appropriate places in your TestCase's.
Looking at your code, it seems that 'login' is your test module and 'login_bms' contains your test util functions, so you're on the right track already. Just import and call stuff inside login_bms as functions and do not try to attach them to a specific TestCase.
setrofim
 
Posts: 288
Joined: Mon Mar 04, 2013 7:52 pm


Return to General Coding Help

Who is online

Users browsing this forum: No registered users and 7 guests