python+selenium自动化软件测试(第10章):测试驱动TDD

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python+selenium自动化软件测试(第10章):测试驱动TDD相关的知识,希望对你有一定的参考价值。

测试驱动开发模式,要求开发在写业务代码的时候,先写出测试代码,同时单元测试例子决定了如何来写产品的代码,并且不断的成功的执行编写的所有的单元测试例子,不断的完善单元测试例子进而完善产品代码, 这样随着功能的开发完成,测试代码也会对应的完成, 很显然,这是一个全新的开发模式, 在一定程度上,可以完全的提高软件的质量,以及开发可以对自己写的代码进行一个全面的评估和测试。

TDD 模式是一个很大的概念,在这里, 我重点介绍下测试驱动模式与自动化的融合以及精简自动化的测试代码。
下面我们来看一个登录的案例:

coding:utf-8
import unittest
from selenium import webdriver

class developTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.driver.maximize_window()
        self.driver.get(http://xxxx/login)
        self.addCleanup(self.driver.quit)

    def testLogin(self):
    #用户名输入
    name = self.driver.find_element_by_id(xxxx)
    name.clean()
    name.send_keys(xxxx)

    #密码输入
    passwd = self.driver.find_element_by_id(xxxx)
    passwd.clear()
    passwd.send_keys(xxxx)

    #点击登录
    self.driver.find_element_by_id(xxxx).click()

    #获取到用户昵称
    userName = self.driver.find_element_by_xpath("xxx")
    userlnfo = userName.text

    #退出系统
    userName.click()
    self.driver.find_element_by_xpath("xxxx").click()
    self.assentTrue(userlnfo in linux)

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

如上的代码, 我们成功的实现了登录 ,获取到用户的昵称,退出系统,以及验证用户昵称这样的一个过程, 但是问题也就来了,如果我登录系统 N 次以及退出系统次,那么就意味着写登录退出就得 N次,很明显,这样很多的登录退出的代码都是一致的,增加了工作量,如下, 我通过把登录,退出,获取到用户昵称,写成一个单独的函数,然后使用到了直接调用对应的函数(调用的时候记得导入), 文件名称是 kuihua.py, 具体代码为如下:

#coding:utf-8
#登录函数

def login(driver,usenname=I59xxxxx,password=server):
    driver.find_element_by_id(xxxx).send_keys(usenname)
    driver.find_element_by_id(xxxx).send_keys(password)
    driver.find_element_by_id(xxxx).click()

#获取用户昵称
def getName(driver):
    return driver.find_element_by_xpath("xxxx").text

#退出系统
def exitSystem(driver):

dniver.find_element_by_xpath("xxxx").click()
dniver.find_element_by_xpath("xxxx").click()

如上函数之后,测试脚本就精简很多了,测试脚本见如下:

#coding:utf-8
import unittest
from selenium import webdriver
import kuihua

class developTest(unittest.TestCase):
  def setUp(self):
    self.driver=webdriver.Firefox()
    self.driver.implicitly_wait(30)
    self.driver.maximize_window()
    self.driver.get(http://my.weke.com/login.html)
    self.addCleanup(self.driver.quit)

  def testLogin(self):
    kuihua.login(self.driver)
    userInfo=vke.getName(self.driver)
    vke.exitSystem(self.driver)
    self.assentTrue(usenInfo in linux)

if __name == __main__:
    unittest.main(verbosity=2)

通过这样的一个实例, 我们把测试脚本精简了很多,其实还可以把最后一步精简下,但是我一般感觉,最后一步还是在测试代码中比较好,因此我们可以总结出如下几点:
1、 对于某些公用的功能,如登录,退出,单独写成一个函数, 需要
的时候,直接调用函数;
2、 验证点一定要写在最后一步,本实例验证用户昵称部分,不可以写在退出之前验证,先获取到用户昵称,退出系统,再验证用户昵称
3、 尽量保持测试脚本与页面对象元素分离开,这样即使系统需求变更或者开发把页面元素更改了,我们只在一个地方维护,而不影响 tescase 的脚本。虽然我们实现了把测试用例的代码精简化, 实现了测试脚本与页面对象的分离,实现了后期维护页面对象只在一个地方维护,但是还是存在很多的缺点, 我们可不可以把使用到的数据,页面对象放在.csv.xml 文件中了?答案当然是可以, 下来部分我们重点介绍把使用到的数据放在.txt, .csv, . xlsx, xml 文件中, 同时介绍 ddt 模块的安装以及使用方法, 来继续重构我们的测试代码。

10.1 ddt 模块

ddt 是 python 的第三库, 全名称为: Data-Driven/Decorated Tests。ddt 模块提供了创建数据驱动的测试,关于该模块,建议到官方查看详细的说明, 安装方法分别为命令行安装或者下载文件进行安装,分别进行说明,二种安装的方式具体见如下:
1、下载ddt文件,让后解压,到解压的目录下,输入: pythonsetup.py install 安装,见如下的截图:

技术分享

 

2、 直接使用 pip 在线安装 ddt, 命令为: pip install ddt

技术分享

在实际自动化测试中的应用,代码如下:

 

#coding:utf-8

import unittest
from selenium import webdriver
from ddt import ddt,data,unpack
from time import sleep

@ddt
class developTest(unittest.TestCase):
    def setUp(self):
    self.driver = webdriver.Firefox()
    self.driver.implicitly_wait(30)
    self.driver.maximize_window()
    self.driver.get(http://www.baidu.com)
    self.addcleanup(self.driver.quit)@data((‘‘,‘‘,u手机/邮箱/用户名),(admin,‘‘,u请您填写密码),(admin,admin,u您输入的帐号或密码有误,忘记密码?))

@unpack
def testLogin(self, sendValue1, sendValue2, expected):
    self.driver.find_element_by_link_text(u登录’).click()
    sleep(2)
    #输入百度账号
    userName=self.driver.find_element_by_id(xxxx)
    userName.clear()
    userMame.send_keys(sendValuel)

    #输入百度密码
    password=self.driver.find_element_by_id(xxxxx)
    password.clear()
    password.send_keys(sendValue2)

    #点击登录按钮
    self.driver.find_element_by_id(xxxxx).click()
    #获取到返回的错误信息
    errorText=self.driver.find_element_by_xpath("xxxxx").text
    self.assentTrue(emonText, expected)

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

 

从如上的代码以及执行结果的截图,我们可以地得到,这个测试用例
验证了三个验证点, 分别是:
1、 百度账号为空, 密码为空, 点击登录按钮, 验证返回的错误信息
2、 输入百度账号,未输入密码, 验证返回的错误信息
3、 输入错误的账号和错误的密码, 验证返回的错误信息
但是我们的核心代码只有如下的几行:

技术分享

ddt 模块的优秀之处, 几行代码,实现多个测试点, 可以少写了很多代码。

10.2 csv 文件的处理

python提供了对 csv文件处理的模块,直接 import csv就可以了,那么神秘是 csv 文件了? csv 文件全名称为 Comma-SeparatedValues,csv 是通用的,相对简单的文件格式,其文件已纯文件形式存储数据。 我们把数据存储在 csv 的文件中,然后写一个函数获取到 csv文件的数据, 在自动化中引用,这样,我们自动化中使用到的数据,就可以直接在 csv 文件中维护了,见下面的一个 csv 文件的格式:

技术分享

下面我们实现读写 csv 文件中的数据,具体见如下实现的代码:

技术分享

技术分享

为了具体读取到 csv 文件中某一列的数据,我们可以把读取 csv 文件的方法修改如下,见代码:

技术分享

如我们需要读取第一个 selenium, csv 文件内容见如上的截图,那么调用的方法代码为:

技术分享

执行后如下截图:

技术分享

已百度搜索输入框为实例,在搜索输入框输入 csv 文件中的字符,我们把读写 csv 文件的函数写在 location.py 的模块中,见 location.py的源码:

#coding:utf-8
import csv
#读取CSV的文件
def getCsv(valuel,value2,file_name=d:/test.csv):
    nows=[]
    with open(file_name,nb) as f:
    neaders=csv.reader(f,delimiterst ,quotechar=|)
    next(readers^None)

for row in readers:
    rows.append(row)
    return rows[valuel][value2]

#csv文件中写数据
def writeCsv(file_name=d:/test.csv):
    with open(file_name,wb) as f:
    wnite=csv.writer(f)
    write.writerow([Element,system])data=[
    (selenium‘‘webdriver),
    (appium,android),
    (appium,ios),
    (selenium,python)]

write.writerows(data)
f.close()

 

把测试代码写在 baiduTest.py 的模块中,见该模块的源码:

#coding:utf-8

from selenium import webdriver
import location
import unittest
import time
time.sleep(5)

class BaiduTest(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Firefox()
        self.driver.maximize_window()
        self.driver.implicitly一wait(30)
        self.driver.get(location.getCsv(4,0))

    def testCase_01(self):
        ‘‘‘获取CSV文件中第二列第_位的数据进行搜索‘‘‘
        self.driver.find_element_by_id(kw).send_keys(location.getCsv(l,0))

    def tearDown(self):
        self.driver.quit()

if __name__==__main__:
suite = unittest.TestLoader().loadTestsFnomTestCase(BaiduTest)
unittest.TextTestRunner(verbosity=2).run(suite)

在如上的测试代码中,我把 url,以及搜索的字符都放在了 csv 的文件中,在测试脚本中,只需要调用读取 csv 文件的函数,这样,我们就可以实现了把测试使用到的数据存储在 csv 的文件中,来进行处理。
在前面我这边介绍到了 ddt 的模块,那么现在我这边 ddt 模块和csv 文件结合,来进行自动化的测试,编辑后的 csv 文件后:

技术分享

 

我重新写 location.py 的模块,具体见该模块的源码:

#coding:utf-8

import csv

def getCsv(file_name):
rows=[]
with open(file_name, rb) as f:
readers = csv.reader(f, delimiter=,, quotechar=|)
next(readers, None)

for row in readers:
    rows.append(row)
return rows

实现在百度搜索输入框输入搜索关键字分别是 selenium,appium,那么实现的测试模块 baiduTest.py 的源码为:

#coding:utf-8

from selenium import webdriver
from ddt import ddt,data,unpack
import location
import time


import unittest, sys
neload(sys)
sys.setdefaultencoding(utf-8)

@ddt
class BaiduTest(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Firefox()self.driver.maximize_window()
        self.driver.implicitly_wait(30)
        self.driver.get(http://www.baidu.com/)
        @data(*location.getCsv("d:\\\\xxx.csv"))

    @unpack
    def testCase_01(self,actual,expect):
    ‘‘‘ddt模块与csv文件结合的使用‘‘‘
    self.driver.find_element_by_id(kw).send_keys(actual)

    time.sleep(5)

    def tearDown(self):
        self.driver.quit()

if __name__ == __main__:
    suite=unittest.TestLoader().loadTestsFromTestCase(BaiduTest)
    unittest.TextTestRunner(verbosity=2).run(suite)

我们就实现了单独读取 csv 文件中的内容,或者 csv 文件和 ddt模块结合来在自动化中使用。

 

以上是关于python+selenium自动化软件测试(第10章):测试驱动TDD的主要内容,如果未能解决你的问题,请参考以下文章

python+selenium自动化软件测试(第8章) 多线程

python+selenium自动化软件测试(第6章):selenium phantomjs页面解析使用

python+selenium自动化软件测试(第14章):基础实战

SELENIUM 2 自动化测试实战 基于PYTHON语言pdf

python+selenium自动化软件测试(第16章):基础实战

Selenium_python自动化第一个测试案例(代码基本规范)