python selenium自動化測試

簡易selenium自動化測試框架(Python)

最近空閒時間在探索Selenium的自動化測試,簡單的寫了一個小框架來測試公司的一個web產品。該框架包括以下模塊:

1. Test case編寫模式(page模式,參考之前的博文http://www.cnblogs.com/AlwinXu/p/5537955.html)

2. Test case的管理及執行 (主要是用nose)

  該模塊藉助了一個外部txt文件來記錄測試用例,每個用例爲自身的文件名,如果不需要在本次執行,只需在文件名前添加一個“#”標識符就可以跳過該用例的執行。

3. 測試報告的生成(xml和html兩種格式)

 

對於自動化測試而言,這些模塊應該是最基本的配置了,當然還有一些輔助模塊比如日誌,其他公共庫模塊等需要根據具體的業務逐漸豐富。閒話少說,用代碼交流吧。

測試用例編寫

該模塊用了Page模式,之前介紹過,這次只貼代碼了

BasePage.py:

__author__ = 'xua'#super classclass BasePage(object):    def __init__(self, driver):
        self.driver = driver

然後是各個web page繼承BasePage,LoginPage.py:

複製代碼

from BasePage import BasePagefrom selenium.webdriver.common.by import Byfrom selenium.webdriver.common.keys import Keysclass LoginPage(BasePage):    """description of class"""

    #page element identifier
    usename = (By.ID,'username')
    password = (By.ID, 'password')
    dialogTitle = (By.XPATH,'//html/body/div[7]/div/div/div[1]/h3')
    cancelButton = (By.XPATH,'//html/body/div[7]/div/div/div[3]/button[2]')    #Get username textbox and input username
    def set_username(self,username):
        name = self.driver.find_element(*LoginPage.usename)
        name.send_keys(username)    
    #Get password textbox and input password, then hit return
    def set_password(self, password):
        pwd = self.driver.find_element(*LoginPage.password)
        pwd.send_keys(password + Keys.RETURN)    #Get pop up dialog title
    def get_DiaglogTitle(self):
        digTitle = self.driver.find_element(*LoginPage.dialogTitle)        return digTitle.text    #Get "cancel" button and then click
    def click_cancel(self):
        cancelbtn = self.driver.find_element(*LoginPage.cancelButton)
        cancelbtn.click()

複製代碼

測試用例信息類:

TestCaseInfo.py

複製代碼

class TestCaseInfo(object):    """description of class"""

    def __init__(self, id="",name="",owner="",result="Failed",starttime="",endtime="",errorinfo=""):
        self.id = id
        self.name = name
        self.owner = owner
        self.result = result
        self.starttime = starttime
        self.endtime = endtime
        self.errorinfo = errorinfo

複製代碼

 

最後是每個測試用例的編寫:(每個用例必須有自己的用例信息,這裏有ID,Name等等信息,也會調用測試結果報告生成模塊來添加測試結果)

Test_Login.py

複製代碼

__author__ = 'xua'from selenium import webdriverfrom selenium.webdriver.common.keys import Keysfrom selenium.webdriver.common.alert import Alertimport unittestimport timefrom LoginPage import LoginPagefrom TestCaseInfo import TestCaseInfofrom TestReport import TestReportclass Test_Login(unittest.TestCase):    #Setup
    def setUp(self):
        self.driver = webdriver.Chrome(r'C:\Users\xua\Downloads\chromedriver_win32\chromedriver.exe')
        self.driver.implicitly_wait(30)
        self.base_url = "http://10.222.30.145:9000/"
        #test case information
        self.testcaseinfo = TestCaseInfo(id="3",name="Login to floor manager lite using sbxadmin",owner="xua")
        self.testResult = TestReport()  
    def test_Login(self):        try:
            self.testcaseinfo.starttime = str(time.asctime())            #Step1: open base site            self.driver.get(self.base_url)            #Step2: Open Login page
            login_page = LoginPage(self.driver)            #Step3: Enter username
            login_page.set_username("sbXadmin")            #Step4: Enter password
            login_page.set_password("IGTtest1")            #Checkpoint1: Check popup dialog title
            self.assertEqual(login_page.get_DiaglogTitle(),"Sign in","Not Equal")            #Step5: Cancel dialog            login_page.click_cancel()
            self.testcaseinfo.result = "Pass"
        except Exception as err:
            self.testcaseinfo.errorinfo = str(err)        finally:
            self.testcaseinfo.endtime = str(time.asctime())    #tearDown
    def tearDown(self):
        self.driver.close()        #write test result        self.testResult.WriteHTML(self.testcaseinfo)if __name__ == "__main__":
    unittest.main()

複製代碼

用例執行模塊

1. 藉助外部文件記錄需要執行的用例

testcases.txt(帶“#”標識的用例不會被執行):

Test_Login.py
Test_Login_2.py#Test_Login_3.py
Test_Login_4.py

2. 利用nose的nosetests命令執行各個用例:

複製代碼

import subprocessclass RunTests(object):    """description of class"""
    def __init__(self):
        self.testcaselistfile = "testcases.txt"
    
    #use nosetests command to execute test case list
    def LoadAndRunTestCases(self):
        f = open(self.testcaselistfile)
        testfiles = [test for test in f.readlines() if not test.startswith("#")]
        f.close()        for item in testfiles:
            subprocess.call("nosetests "+str(item).replace("\\n",""),shell = True)if __name__ == "__main__":
    newrun = RunTests()
    newrun.LoadAndRunTestCases()

複製代碼

測試結果報表生成模塊

測試報表模塊寫了兩種格式:xml和html

TestReport.py

複製代碼

from xml.etree import ElementTree as ETimport osimport lxml.etree as mytreefrom lxml import htmlclass TestReport(object):    """description of class"""
    def __init__(self):
        self.testreport = "TestResult.xml"

    #If there is no "TestResult.xml", then create one
    def CreateTestResultFile(self):        if os.path.exists(self.testreport) == False:
            newElem = ET.Element("TestCases")
            newTree = ET.ElementTree(newElem)
            newTree.write(self.testreport)                        
    #Write test result to xml
    def WriteResult(self,testcaseInfo):
        self.CreateTestResultFile()
        testResultFile = ET.parse(self.testreport)
        root = testResultFile.getroot()
        newElem = ET.Element("TestCase")
        newElem.attrib = {            "ID":testcaseInfo.id,            "Name":testcaseInfo.name,            "Owner":testcaseInfo.owner,            "Result":testcaseInfo.result,            "StartTime":testcaseInfo.starttime,            "EndTime":testcaseInfo.endtime,            "ErrorInfo":testcaseInfo.errorinfo
            }
        root.append(newElem)

        testResultFile.write(self.testreport)    #If there is no "TestResult.html" file exists, then create one with default style
    def CreateHtmlFile(self):        if os.path.exists("TestResult.html") == False:
            f = open("TestResult.html",'w')
            message = """<html>
            <head>    
                <title>Automation Test Result</title>
                <style>
                    table {
                            border-collapse: collapse;
                            padding: 15px;
                            font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
                            }
                    th{
                        background-color: green;
                        color: white;
                        border: 1px solid #ddd;
                        padding-bottom: 15px;
                        padding-top: 15px;
                    }
                    tr{
                        border: 1px solid #008000;
                        padding-bottom: 8px;
                        padding-top: 8px;
                        text-align: left;
                    }
                    td{
                        border: 1px solid #008000;
                    } 
                </style>
            </head>
            <body>
                <h1>Automation Test Result</h1>
                <table>
                    <tr>
                        <th>ID</th>
                        <th>Name</th>
                        <th>Owner</th>
                        <th>Result</th>
                        <th>StartTime</th>
                        <th>EndTime</th>
                        <th>ErrorMessage</th>
                   </tr>
                </table>
            </body>
            </html>            """
            f.write(message)
            f.close()    #append new test result to testresult file
    def WriteHTML(self,testcaseinfo):

        self.CreateHtmlFile()

        f = open("TestResult.html","r")
        
        htmlcontent = f.read()
        f.close()
        tree = html.fromstring(htmlcontent)
        tableElem = tree.find(".//table")        if testcaseinfo.result == "Failed":
            mytablerow = "<tr><td>{0}</td><td>{1}</td><td>{2}</td><td bgcolor=\"#FF0000\">{3}</td><td>{4}</td><td>{5}</td><td>{6}</td></tr>".format(testcaseinfo.id,testcaseinfo.name,testcaseinfo.owner,testcaseinfo.result,testcaseinfo.starttime,testcaseinfo.endtime,testcaseinfo.errorinfo)        else:
            mytablerow = "<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td></tr>".format(testcaseinfo.id,testcaseinfo.name,testcaseinfo.owner,testcaseinfo.result,testcaseinfo.starttime,testcaseinfo.endtime,testcaseinfo.errorinfo)
        tableElem.append(mytree.HTML(str(mytablerow)))

        f = open("TestResult.html","w")        #html.tostring
        newContent = repr(html.tostring(tree,method="html",with_tail=False))
        newContent = newContent.replace(r"\n","").replace(r"\t","").replace('b\'',"")
        newContent = newContent[:len(newContent)-1]
        f.write(newContent)
        f.close()

複製代碼

ok,最後看一下生成的測試報表:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章