这个还是我在刚开始学习selenium的时候做的,自己觉得有点意思,在接下来我会基于目前我对于selenium的一些深入研究,写下我对selenium的理解以及UIAutomation的一些理解,以此开篇吧^_^

前段时间研究Selenium,写了一些测试网页的代码,写着写着,就感觉这些自动化cases的相似度太高,多数是大同小异,基本上可以归纳为这样三步1)找到元素 2)进行操作, 比如点击或者滑动 3) 验证期望, 比如跳转到了一个新页面,或者新元素出现在屏幕中.

比如下面:

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
def web_automation():
browser=webdriver.Chrome()
browser.get('http://www.baidu.com/') Input_element=browser.find_element_by_id('kw')
Input_element.send_keys('Selenium')
browser.find_element_by_id('su').click()
result=browser.find_element_by_xpath('//*[@id="container"]/div[2]').is_displayed() assert result!=True,"Failed"

写的多了,这时候就想,能不能有什么模板,让我们快速的创建一条case,甚或者能让一个不会Selenium的Tester也能写自动化case呢。

说做就做,最后就搞出来了下面一个雏形, 我们可以定义这样的一个XML:

    <TestCase name="ClickBackButton" scriptVersion="1.0.0">
<Executable>Chrome</Executable>
<Address>http://www.baidu.com</Address>
<Action Operate="InputSearchInfo" Type="Input" ID="kw" Content="Glow"/>
<Action Operate="Scroll" Type="Scroll" />
<Action Operate="ClickNextPageHLink" Type="Click" XPath='//*[@id="page"]/a[10]'>
<Expected XPath='//*[@id="page"]/strong/span[2]' Text="2" />
</Action>
<Action Operate="Goback" Type="Back">
<Expected XPath='//*[@id="page"]/strong/span[2]' Text="1" />
</Action>
<Action Operate="Scroll" Type="Scroll" />
<Action Operate="ClickPage6" Type="Click" XPath='//*[@id="page"]/a[5]'>
<Expected XPath='//*[@id="page"]/strong/span[2]' Text="6" />
</Action>
<Action Operate="Goback" Type="Back">
<Expected XPath='//*[@id="page"]/strong/span[2]' Text="1" />
</Action>
</TestCase>

然后我们就可以这样来解析:

第一步解析XML生成TestCase的list,在例子中就一个Testcase:

import xml.etree.ElementTree as ET
import logging
import os
import sys
import traceback
from TestCase import TestCase class ParseCase:
def __init__(self,xml_path):
if os.path.exists(os.getcwd()+"\\"+xml_path) or os.path.exists(xml_path):
self.caseList=[]
try:
xml=ET.parse(xml_path)
root=xml.getroot()
self.caseList=root.find('TestList').findall('TestCase')
except IOError as e:
print traceback.format_exc()
logging.debug(traceback.format_exc())
if self.caseList:
logging.info('No Testcase detected')
else:
logging.info('No Testcase detected')
else:
print "XML file is not exists"
logging.debug("XML file is not exists") def getAllTestCaseList(self):
TestCases=[]
for case in self.caseList:
_testcase=TestCase(case)
TestCases.append(_testcase)
return TestCases

第二步, 根据每个testcase建立TestCase类的实例:

class TestCase:
def __init__(self, _testcase):
self.name=_testcase.attrib['name']
_list=[]
self.actions=[]
try:
_list=_testcase.getchildren()
except Exception,msg:
print msg
self._executor=_testcase.find('Executable').text
self.address=_testcase.find('Address').text
for act in _testcase.findall('Action'):
if act.tag=='Action':
_action=Action(act)
self.actions.append(_action) def setUp(self):
if 'Chrome'==self._executor:
self.executor=webdriver.Chrome()
elif 'Firefox'==self._executor:
self.executor=webdriver.Firefox()
else:
self.executor=webdriver.Ie()
self.executor.get(self.address) def tearDown(self):
self.executor.quit() def execute(self):
logging.debug("Start to execute the testcase:%s" % self.name)
print "TestCaseName:%s" % self.name
try:
self.setUp()
for action in self.actions:
action.execute(self.executor);
self.tearDown()
Assert.AssertPass("TestCase:%s " % self.name)
except Exception as error:
print error
self.tearDown()
Assert.AssertFail("TestCase:%s " % self.name)

第三步,根据xml里定义的type来触发动作,我就简单的列了下:

    def execute(self,executor):
_type=self._actions['Type']
self.getBy(self._actions)
try:
if self.by!=None:
ele=self.findElement(executor)
Assert.AssertIsNotNull(ele," ".join("Find element by %s:%s" % (str(self.by),self.by_value)))
if _type=='Input':
ele.send_keys(self._actions['Content'])
time.sleep(3) elif _type=='Click':
ele.click()
elif _type=='Scroll':
webOperate.page_scroll(executor)
elif _type=='Back':
webOperate.goBack(executor) else:
print " ",
Assert.AssertFail(self._name)
print "No such action:%s" % _type
if self._expected is not None:
Assert.AssertIsTrue(self.isExpected(executor)," ".join("Find element by %s:%s" % (str(self.by),self.by_value)))
print " ",
Assert.AssertPass(self._name)
except AssertionError:
print " ",
Assert.AssertFail(self._name)
raise AssertionError(self._name +" execute failed")

看一个运行的截图

代码比较简单,原理也很清晰,就是解析XML文件,然后调用相应的selenium代码,但是如果我们再深入的想想,在解析这些XML的时候,是不是可以以更友好的方式来展示生成的代码呢,甚或者以UI的方式,一条条展示。然后再提供可编辑功能?甚或者再提供录制的方式来自动生成这些XML文件,再解析成代码,这不就是一个强大的自动化测试工具??

学习selenium python版最初的一个小想法的更多相关文章

  1. 数据科学的完整学习路径—Python版(转载)

    时间 2015-01-29 14:14:11  数盟原文  http://dataunion.org/?p=9805 译者: Allen 从Python菜鸟到Python Kaggler的旅程(译注: ...

  2. python新手第一天学习笔记-python循环控制和第一个python小游戏

    Python的三种逻辑控制 1.python语法. python 是以缩进作为基本判断的.同一代码缩进需要保持一致.否则会报错 1.if 的三种循环 _age = 53 # 注意,input接受的都是 ...

  3. python练习册 每天一个小程序 第0000题

    PIL库学习链接:http://blog.csdn.net/column/details/pythonpil.html?&page=1 1 #-*-coding:utf-8-*- 2 __au ...

  4. extJs学习基础5 理解mvvm的一个小案例

    今天很是幸运,看到了一位大神的博客,学习了不少的东西.太感谢了.(满满的都是爱啊) 建议去学习这个大神的博客,真心不错. 博客地址:http://blog.csdn.net/column/detail ...

  5. Python数学运算的一个小算法(求一元二次方程的实根)

    请定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程:ax² + bx + c = 0的两个解. #!/usr/bin/env python # -*- coding: ...

  6. python练习册 每天一个小程序 第0013题

    # -*-coding:utf-8-*- ''' 题目描述: 用 Python 写一个爬图片的程序,爬 这个链接里的日本妹子图片 :-) 地址: http://tieba.baidu.com/p/21 ...

  7. python练习册 每天一个小程序 第0001题

    1 # -*-coding:utf-8-*- 2 __author__ = 'Deen' 3 ''' 4 题目描述: 5 做为 Apple Store App 独立开发者,你要搞限时促销,为你的应用生 ...

  8. JAVA学习笔记(一):一个小爬虫的例子

    1.import java.io.*;   java.io.*不是一个文件,而是一组类.它是在java.io包里的所有类,*是通配符,比如a*.txt代表的就是以a开头的所有txt文件,“?”是单个词 ...

  9. windows平台python svn模块的一个小 bug

    环境 编程语言版本:python 2.7 操作系统:win10 64位 模块名:svn svn  checkout时报错 File "D:\Python27\lib\site-package ...

随机推荐

  1. 4.mysql数据库创建,表中创建模具模板脚本,mysql_SQL99标准连接查询(恩,外部连接,全外连接,交叉连接)

     mysql数据库创建,表创建模等模板脚本 -- 用root用户登录系统,运行脚本 -- 创建数据库 create database mydb61 character set utf8 ; -- ...

  2. Linux netstat订购具体解释

    简单介绍 Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics).masquerade 连接.多播成员 (Multicast Memb ...

  3. LeetCode——Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  4. keyboard splitting bug on ipad with ios 5 and 6 (Cocos2d-x)

    Had the same issue - the solution is to stop the opengl layer from rendering while this is happening ...

  5. 大数据系列修炼-Scala课程10

    今天主要是关于Scala中对List的相关操作,list在Scala中应该是至关重要,接下来会讲解关于List的一系列操作 List的map.flatMap.foreach.filter操作讲解 1. ...

  6. HttpGet 请求

    import java.net.HttpURLConnection; import java.text.SimpleDateFormat; import java.util.Calendar; imp ...

  7. C#将Excel数据导入数据库(MySQL或Sql Server)

    最近一直很忙,很久没写博客了.今天给大家讲解一下如何用C#将Excel数据导入Excel,同时在文章最后附上如何用sqlserver和mysql工具导入数据. 导入过程大致分为两步: 1.将excel ...

  8. 在VirtualBox安装OS X 10.10

    下面将指导介绍了如何引入自由和强大VirtualBox安装在虚拟机上OS X Yosemite 10.10 法律免责声明:本指南旨在说明如何在定期购买的苹果电脑上创建一个虚拟机执行真正的Mac OS ...

  9. 开发现代ASP.NET应用程序

    新思想.新技术.新架构——更好更快的开发现代ASP.NET应用程序(续1)   今天在@张善友和@田园里的蟋蟀的博客看到微软“.Net社区虚拟大会”dotnetConf2015的信息,感谢他们的真诚付 ...

  10. 在Installshield的安装进度中显示自己设置的信息

    原文:在Installshield的安装进度中显示自己设置的信息 以Installscript msi project为例,在installshield所制作的安装包安装过程中显示安装进度的,就在On ...