Selenium2 Python 自动化测试实战学习笔记(五)

时间:2022-03-24 07:33:29

    

7.1 自动化测试用例

         不管是功能测试、性能测试和自动化测试时都需要编写测试用例,测试用例的好坏能准确的体现了测试人员的经验、能力以及对项目的深度理解。

7.1.1 手工测试用例与自动化测试用例

         手工测试用例是针对手工测试人员,自动化测试用例是针对自动化测试框架,前者是手工测试用例人员应用手工方式进行用例解析,后者是应用脚本技术进行用例解析。

         前者具有较好的异常处理能力,而且能够基于测试用例,制造各种不同的逻辑判断,而且人工测试步步跟踪,能够细致定位问题。后者完全按照测试用例的步骤进行测试,只能在已知的步骤和场景中发现问题,而且往往因为网络问题或者功能的微小的变化导致用例执行异常,自动化的执行也很能发现新的bug。

         手工测试用例和自动化测试用对比:

         手工测试用例:

l  较好的异常处理能力,能通过人为的逻辑判断校验当前步骤的功能实现正确与否。

l  人工执行用例具有一定的步骤跳跃性。

l  人工测试步步跟踪,能够细致的定位问题。

l  主要用来发现功能缺陷

 

自动化测试用例:

l  执行对象是脚本,任何一个判断都需要编码定义。

l  用例步骤之间关联性强。

l  主要用来保证产品主体功能正确完整和让测试人员从繁琐重复的工作中解脱出来。

l  目前自动化测试阶段定位在冒烟测试和回归测试。

 

自动化测试用例选型注意事项:

1.  不是所有的手工用例都要转为自动化测试用例。

2. 考虑到脚本开发的成本,不要选择流程太复杂的用例。如果有必要,可以考虑把流程拆分多个用例来实现脚本。

3.      选择的用例最好可以构建成场景。例如一个功能模块,分n 个用例,这n 个用例使用同一个场景。这样的好处在于方便构建关键字测试模型。

4.      选择的用例可以带有目的性,例如这部分用例是用例做冒烟测试,那部分是回归测试等,当然,会存在重叠的关系。如果当前用例不能满足需求,那么唯有修改用例来适应脚本和需求。

5.      选取的用例可以是你认为是重复执行,很繁琐的部分,例如字段验证,提示信息验证这类。这部分适用回归测试。

6.      选取的用例可以是主体流程,这部分适用冒烟测试。

7. 自动化测试也可以用来做配置检查,数据库检查。这些可能超越了手工用例,但是也算用例拓展的一部分。项目负责人可以有选择地增加。

8. 如果平时在手工测试时,需要构造一些复杂数据,或重复一些简单机械式动作,告诉自动化脚本,让他来帮你。或许你的效率因此又提高了。

7.1.2 测试类型

 静态内容测试是最简单的测试,用于验证静态的、不变化的UI 元素的存在性。例如:

每个页面都有其预期的页面标题?这可以用来验证链接指向一个预期的页面。

•应用程序的主页包含一个应该在页面顶部的图片吗?

•网站的每一个页面是否都包含一个页脚区域来显示公司的联系方式,隐私政策,以及商标信息?

•每一页的标题文本都使用的<h1>标签吗?每个页面有正确的头部文本内吗?

您可能需要或也可能不需要对页面内容进行自动化测试。如果您的网页内容是不易受到影响手工对内容进行测试就足够了。如果,例如您的应用文件的位置被移动,内容测试就非常有价值。

 

测试链接:Web 站点的一个常见错误为的失效的链接或链接指向无效页。链接测试涉及点各个链接和验证预期的页面是否存在。如果静态链接不经常更改,手动测试就足够。但是,如果你的网页设计师经常改变链接,或者文件不时被重定向,链接测试应该实现自动化。

 

功能测试通常是需要自动化测试的最复杂的测试类型,但也通常是最重要的。典型的测试是登录,注册网站账户,用户帐户操作,帐户设置变化,复杂的数据检索操作等等。功能测试通常对应着您的应用程序的描述应用特性或设计的使用场景。

 

测试动态元素:通常一个网页元素都有一个唯一的标识符,用于唯一地定位该网页中的元素。通常情况下,唯一标识符用HTML 标记的’id’属性或’name’属性来实现。这些标识符可以是一个静态的,即不变的、字符串常量。

 

Ajax 的测试:Ajax 是一种支持动态改变用户界面元素的技术。页面元素可以动态更改,但不需要浏览器重新载入页面,如动画,RSS源,其他实时数据更新等等。Ajax 有不计其数的更新网页上的元素的方法。但是了解AJAX的最简单的方式,可以这样想,在Ajax 驱动的应用程序中,数据可以从应用服务器检索,然后显示在页面上,而不需重新加载整个页面。只有一小部分的页面,或者只有元素本身被重新加载。

 

在编写用例过程中应该遵守以下几点原则:

1、一个脚本是一个完整的场景,从用户登陆操作到用户退出系统关闭浏览器。

2、一个脚本脚本只验证一个功能点,不要试图用户登陆系统后把所有的功能都进行验证再退出系统

3、尽量只做功能中正向逻辑的验证,不要考虑太多逆向逻辑的验证,逆向逻辑的情况很多(例如手号输错有很多种情况),验证一方面比较复杂,需要编写大量的脚本,另一方面自动化脚本本身比较脆弱,很多非正常的逻辑的验证能力不强。(我们尽量遵循用户正常使用原则编写脚本即可)

4、脚本之间不要产生关联性,也就是说编写的每一个脚本都是独立的,不能依赖或影响其他脚本。

5、如果对数据进行了修改,需要对数据进行还原。

6、在整个脚本中只对验证点进行验证,不要对整个脚本每一步都做验证。

 

 


8.1  使用HTMLTestRunner生成测试报告

HTMLTestRunner 是Python 标准库的unittest 单元测试框架的一个扩展。它生成易于使用的HTML 测试报告。HTMLTestRunner 是在BSD 许可证下发布。

首先要下HTMLTestRunner.py 文件,下载地址:

http://tungwaiyip.info/software/HTMLTestRunner.html

HTMLTestRunner.py 本是一个.py 文件,将它放到Python 安装目录下即可调用。

Windows :将下载的文件放入...\Python27\Lib目录下。

 

在Python 交互模式引入HTMLTestRunner 包,如果没有报错,则说明添加成功。

>>> importHTMLTestRunner

8.1.1    生成HTMLTestRunner测试报告

testBaidu.py

#coding=utf-8
fromselenium import webdriver
importunittest,time
importHTMLTestRunner
classMyTest(unittest.TestCase):

def setUp(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(10)
self.base_url ="http://www.baidu.com"

def test_baidu(self):
driver = self.driver
driver.get(self.base_url +"/")
driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys("HTMLTestRunner")
driver.find_element_by_id("su").click()
def tearDown(self):
self.driver.quit()
if__name__=="__main__":
testSuite=unittest.TestSuite()
testSuite.addTest(MyTest("test_baidu"))
Html=".\\result.htm"
fp=file(Html,'wb')

runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u'百度搜索测试报告',description=u'用例执行情况:')
runner.run(testSuite)
fp.close()

         首先将HTMLTestRunner 模块imoport 进来。定义测试报告的存放路径fiename,通过file()将文件以读写的方式打开。

接着调用HTMLTestRunner 模块下的HTMLTestRunner 方法。stream 指定测试报告文件;title 用于定义测试报告的标题;description 用于定义测试报告的副标题。

现在通过HTMLTestRunner 的run()方法来运行测试套件中所组装的测试用例。最后fp.close()来关闭测试报告文件。

 

通过Python 提供的help()来查看类和方法的说明。

        >>> import HTMLTestRunner

       >>>help(HTMLTestRunner)

       每次运行测试之前之前都要手动的去修改报告的名称,如果忘记修改就会把之前的报告覆盖,这样做显然会麻烦,那么有没有办法使每次生成的报告名称都不一样并且更有意义,我们可以在报告名称中加入当前时间,这样报告不会重叠并且更清晰的知道生成的前后时间.

        time.time() 获取当前时间戳。

time.ctime() 当前时间的字符串形式。

time.localtime() 当前时间的struct_time形式。

time.strftime() 用来获得当前时间,可以将时间格式化为字符串。

Python 中时间日期格式化符号:

%a                   星期几的简写

%A                   星期几的全称

%w                  十进制表示的星期几(值从06,星期天为0

%d                   十进制表示的每月的第几天

%b                   月份的简写

%B                   月份的全称

%m                  十进制表示的月份

%y                   不带世纪的十进制年份(值从099

%Y                   带世纪部分的十制年份

%H 24             小时制的小时

%I 12               小时制的小时

%p                   本地的AMPM 的等价显示

%M                  十时制表示的分钟数

%S                   十进制的秒数

%f                    十进制的微秒,零填充左边

%Z                   当前时区的名称

%j                    十进制表示的每年的第几天

%U                  一年中的星期数(00-53)星期天为星期的开始

%W                  一年中的星期数(00-53)星期一为星期的开始

%x                   本地相应的日期表示

%X                   本地相应的时间表示

%%                  %号本身

获取当前时间:now = time.strftime("%Y-%m-%d %H_%M_%S")

  目前测试报告只集成到了单个测试文件中,我们的最终目的是将其集成表all_test.py 文件中。下面打开all_test.py 文件,做如下修改:UnitTest\Project\all_test.py

#coding=utf-8
import unittest
import HTMLTestRunner
import time

def creatSuite():
testunit=unittest.TestSuite()
test_dir="C:\\Users\\ewang\\Desktop\\Python_Selenium2\\UnitTest\\Project\\test_case"
discover=unittest.defaultTestLoader.discover(test_dir,pattern="test*.py",top_level_dir=None)

for test_suit in discover:
for test_case in test_suit:
testunit.addTest(test_case)
return testunit

now = time.strftime("%Y-%m-%d%H_%M_%S")
filename ='.\\report\\'+now+'result.html'
fp = file(filename, 'wb')
runner=HTMLTestRunner.HTMLTestRunner(
stream=fp,
title=u'百度搜索测试报告',
description=u'用例执行情况:')


if __name__=="__main__":
alltest=creatSuite()
runner.run(alltest)

8.2 创建定时任务

为了让自动化测试“自动化”起来,现在我们来创建定时任务,使自动化测试脚本在指定的时间自动化运行。创建定时任务的方法有很多,比如,我们可以写一段程序让其在指定的时间运行all_test.py 文件,或者使用系统的定时任务功能在指定的时间运行all_test.py文件。