码迷,mamicode.com
首页 > 编程语言 > 详细

简易selenium自动化测试框架(Python)

时间:2016-06-04 11:56:52      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

最近空闲时间在探索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 class
class BasePage(object):
    def __init__(self, driver):
        self.driver = driver

然后是各个web page继承BasePage,LoginPage.py:

from BasePage import BasePage
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

class 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 webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.alert import Alert
import unittest
import time
from LoginPage import LoginPage
from TestCaseInfo import TestCaseInfo
from TestReport import TestReport

class Test_Login(unittest.TestCase):

    #Setup
    def setUp(self):
        self.driver = webdriver.Chrome(rC:\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 subprocess

class 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 ET
import os
import lxml.etree as mytree
from lxml import html

class 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,最后看一下生成的测试报表:

技术分享

 

总结 

在网上有很多关于Selenium自动化的Best Practice,当然大家也可以根据自己的需求来DIY自己的框架,不管简陋与否,好用才是硬道理:)!

简易selenium自动化测试框架(Python)

标签:

原文地址:http://www.cnblogs.com/AlwinXu/p/5558325.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!