51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1764|回复: 1
打印 上一主题 下一主题

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

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2018-3-14 14:12:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近空闲时间在探索Selenium的自动化测试,简单的写了一个小框架来测试公司的一个web产品。该
框架包括以下模块:



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

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

  该模块借助了一个外部txt文件来记录测试用例,每个用例为自身的文件名,如果不需要在本次执
行,只需在文件名前添加一个“#”标识符就可以跳过该用例的执行。

3. 测试报告的生成(xml和html两种格式)



对于自动化测试而言,这些模块应该是最基本的配置了,当然还有一些辅助模块比如日志,其他公
共库模块等需要根据具体的业务逐渐丰富。闲话少说,用代码交流吧。

测试用例编写
该模块用了Page模式,之前介绍过,这次只贴代码了

  1. BasePage.py:

  2. __author__ = 'xua'

  3. #super class
  4. class BasePage(object):
  5.     def __init__(self, driver):
  6.         self.driver = driver
  7. 然后是各个web page继承BasePage,LoginPage.py:

  8. 复制代码
  9. from BasePage import BasePage
  10. from selenium.webdriver.common.by import By
  11. from selenium.webdriver.common.keys import Keys

  12. class LoginPage(BasePage):
  13.     """description of class"""

  14.     #page element identifier
  15.     usename = (By.ID,'username')
  16.     password = (By.ID, 'password')
  17.     dialogTitle = (By.XPATH,'//html/body/div[7]/div/div/div[1]/h3')
  18.     cancelButton = (By.XPATH,'//html/body/div[7]/div/div/div[3]/button[2]')

  19.     #Get username textbox and input username
  20.     def set_username(self,username):
  21.         name = self.driver.find_element(*LoginPage.usename)
  22.         name.send_keys(username)
  23.    
  24.     #Get password textbox and input password, then hit return
  25.     def set_password(self, password):
  26.         pwd = self.driver.find_element(*LoginPage.password)
  27.         pwd.send_keys(password + Keys.RETURN)

  28.     #Get pop up dialog title
  29.     def get_DiaglogTitle(self):
  30.         digTitle = self.driver.find_element(*LoginPage.dialogTitle)
  31.         return digTitle.text

  32.     #Get "cancel" button and then click
  33.     def click_cancel(self):
  34.         cancelbtn = self.driver.find_element(*LoginPage.cancelButton)
  35.         cancelbtn.click()
  36. 复制代码
  37. 测试用例信息类:

  38. TestCaseInfo.py

  39. 复制代码
  40. class TestCaseInfo(object):
  41.     """description of class"""

  42.     def __init__(self, id="",name="",owner="",result="Failed",starttime="",endtime="",errorinfo=""):
  43.         self.id = id
  44.         self.name = name
  45.         self.owner = owner
  46.         self.result = result
  47.         self.starttime = starttime
  48.         self.endtime = endtime
  49.         self.errorinfo = errorinfo
  50. 复制代码


  51. 最后是每个测试用例的编写:(每个用例必须有自己的用例信息,这里有ID,Name等等信息,也会
  52. 调用测试结果报告生成模块来添加测试结果)

  53. Test_Login.py

  54. 复制代码
  55. __author__ = 'xua'

  56. from selenium import webdriver
  57. from selenium.webdriver.common.keys import Keys
  58. from selenium.webdriver.common.alert import Alert
  59. import unittest
  60. import time
  61. from LoginPage import LoginPage
  62. from TestCaseInfo import TestCaseInfo
  63. from TestReport import TestReport

  64. class Test_Login(unittest.TestCase):

  65.     #Setup
  66.     def setUp(self):
  67.         self.driver = webdriver.Chrome(r'C:\Users\xua\Downloads\chromedriver_win32\chromedriver.
  68. exe')
  69.         self.driver.implicitly_wait(30)
  70.         self.base_url = "http://10.222.30.145:9000/"
  71.         #test case information
  72.         self.testcaseinfo = TestCaseInfo(id="3",name="Login to floor manager lite using sbxadmin",own
  73. er="xua")
  74.         self.testResult = TestReport()
  75.   
  76.     def test_Login(self):
  77.         try:
  78.             self.testcaseinfo.starttime = str(time.asctime())
  79.             #Step1: open base site
  80.             self.driver.get(self.base_url)
  81.             #Step2: Open Login page
  82.             login_page = LoginPage(self.driver)
  83.             #Step3: Enter username
  84.             login_page.set_username("sbXadmin")
  85.             #Step4: Enter password
  86.             login_page.set_password("IGTtest1")
  87.             #Checkpoint1: Check popup dialog title
  88.             self.assertEqual(login_page.get_DiaglogTitle(),"Sign in","Not Equal")
  89.             #Step5: Cancel dialog
  90.             login_page.click_cancel()
  91.             self.testcaseinfo.result = "Pass"
  92.         except Exception as err:
  93.             self.testcaseinfo.errorinfo = str(err)
  94.         finally:
  95.             self.testcaseinfo.endtime = str(time.asctime())

  96.     #tearDown
  97.     def tearDown(self):
  98.         self.driver.close()
  99.         #write test result
  100.         self.testResult.WriteHTML(self.testcaseinfo)

  101. if __name__ == "__main__":
  102.     unittest.main()
复制代码

复制代码
用例执行模块
1. 借助外部文件记录需要执行的用例

testcases.txt(带“#”标识的用例不会被执行):

Test_Login.py
Test_Login_2.py
#Test_Login_3.py
Test_Login_4.py
2. 利用nose的nosetests命令执行各个用例:

复制代码
  1. import subprocess

  2. class RunTests(object):
  3.     """description of class"""
  4.     def __init__(self):
  5.         self.testcaselistfile = "testcases.txt"
  6.    
  7.     #use nosetests command to execute test case list
  8.     def LoadAndRunTestCases(self):
  9.         f = open(self.testcaselistfile)
  10.         testfiles = [test for test in f.readlines() if not test.startswith("#")]
  11.         f.close()
  12.         for item in testfiles:
  13.             subprocess.call("nosetests "+str(item).replace("\\n",""),shell = True)

  14. if __name__ == "__main__":
  15.     newrun = RunTests()
  16.     newrun.LoadAndRunTestCases()
复制代码

复制代码
测试结果报表生成模块
测试报表模块写了两种格式:xml和html

  1. TestReport.py

  2. 复制代码
  3. from xml.etree import ElementTree as ET
  4. import os
  5. import lxml.etree as mytree
  6. from lxml import html

  7. class TestReport(object):
  8.     """description of class"""
  9.     def __init__(self):
  10.         self.testreport = "TestResult.xml"

  11.     #If there is no "TestResult.xml", then create one
  12.     def CreateTestResultFile(self):
  13.         if os.path.exists(self.testreport) == False:
  14.             newElem = ET.Element("TestCases")
  15.             newTree = ET.ElementTree(newElem)
  16.             newTree.write(self.testreport)
  17.                         
  18.     #Write test result to xml
  19.     def WriteResult(self,testcaseInfo):
  20.         self.CreateTestResultFile()
  21.         testResultFile = ET.parse(self.testreport)
  22.         root = testResultFile.getroot()
  23.         newElem = ET.Element("TestCase")
  24.         newElem.attrib = {
  25.             "ID":testcaseInfo.id,
  26.             "Name":testcaseInfo.name,
  27.             "Owner":testcaseInfo.owner,
  28.             "Result":testcaseInfo.result,
  29.             "StartTime":testcaseInfo.starttime,
  30.             "EndTime":testcaseInfo.endtime,
  31.             "ErrorInfo":testcaseInfo.errorinfo
  32.             }
  33.         root.append(newElem)

  34.         testResultFile.write(self.testreport)

  35.     #If there is no "TestResult.html" file exists, then create one with default style
  36.     def CreateHtmlFile(self):
  37.         if os.path.exists("TestResult.html") == False:
  38.             f = open("TestResult.html",'w')
  39.             message = """<html>
  40.             <head>   
  41.                 <title>Automation Test Result</title>
  42.                 <style>
  43.                     table {
  44.                             border-collapse: collapse;
  45.                             padding: 15px;
  46.                             font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  47.                             }
  48.                     th{
  49.                         background-color: green;
  50.                         color: white;
  51.                         border: 1px solid #ddd;
  52.                         padding-bottom: 15px;
  53.                         padding-top: 15px;
  54.                     }
  55.                     tr{
  56.                         border: 1px solid #008000;
  57.                         padding-bottom: 8px;
  58.                         padding-top: 8px;
  59.                         text-align: left;
  60.                     }
  61.                     td{
  62.                         border: 1px solid #008000;
  63.                     }
  64.                 </style>
  65.             </head>
  66.             <body>
  67.                 <h1>Automation Test Result</h1>
  68.                 <table>
  69.                     <tr>
  70.                         <th>ID</th>
  71.                         <th>Name</th>
  72.                         <th>Owner</th>
  73.                         <th>Result</th>
  74.                         <th>StartTime</th>
  75.                         <th>EndTime</th>
  76.                         <th>ErrorMessage</th>
  77.                    </tr>
  78.                 </table>
  79.             </body>
  80.             </html>
  81.             """
  82.             f.write(message)
  83.             f.close()

  84.     #append new test result to testresult file
  85.     def WriteHTML(self,testcaseinfo):

  86.         self.CreateHtmlFile()

  87.         f = open("TestResult.html","r")
  88.         
  89.         htmlcontent = f.read()
  90.         f.close()
  91.         tree = html.fromstring(htmlcontent)
  92.         tableElem = tree.find(".//table")
  93.         if testcaseinfo.result == "Failed":
  94.             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)
  95.         else:
  96.             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)
  97.         tableElem.append(mytree.HTML(str(mytablerow)))

  98.         f = open("TestResult.html","w")
  99.         #html.tostring
  100.         newContent = repr(html.tostring(tree,method="html",with_tail=False))
  101.         newContent = newContent.replace(r"\n","").replace(r"\t","").replace('b\'',"")
  102.         newContent = newContent[:len(newContent)-1]
  103.         f.write(newContent)
  104.         f.close()
复制代码

复制代码
ok,最后看一下生成的测试报表:





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-23 19:31 , Processed in 0.065997 second(s), 26 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表