第六章 移动自动化测试工程的开展(下)
--------手机自动化之Appium
6.6编写自动化测试用例代码
在设计好架构后,我们就需要编写我们的测试用例代码,这个时候也是有方法的。分为以下两种级别:
一, 高级大牛级别。
此级别的测试开发人员非常熟悉具体的业务流程,能设计出每个功能模块所用到的具体操作;清楚可能用到的每个元操作,能拆分出松耦合,使用率高的函数。
在这种情况下,按如下步骤进行我们的自动化测试工程:
(1) 先封装具体的公用函数,测试每个公用函数都测试是否符合预期的要求,如果符合封装完成。编写xml数据读写函数,以便我们对测试数据进行操作。
(2) 组织测试用例需要用到的测试数据,编写对应的测试数据文件Xml,把需要定位操作的定位地址,输入输出数据都放到这个文件中。
(3) 调用公用函数,读取测试数据,组织具体的测试用例,编写测试用例文件并进行调试。
(4) 根据不同的使用场景,如测试环境,仿真环境或是线上环境,组织不同的测试套件文件,灵活使用。
二, 中高级测试开发级别。
一般情况下,我们单独去设计公用函数是很难的,这个需要对业务和自动化测试有非常深入的了解和一定的沉淀。而初次接触或是经验不足的同学,可以采取我们现在的这种方法:从测试用例入手,逐步完善我们的自动化测试工程。这也是我们本章需要详细讲解的问题,我们以实例讲解。
任务:现有一个众筹网的App,需要我们做自动化测试。
条件是:从零开始,一无所有。
已完成的任务:
(1) 测试框架使用Appium开源框架,语言使用python语言。
(2) 相应的环境已搭建完成,编写具体测试用例已能成功运行。
现在的任务是:完成具体的移动自动化测试工程。
具体实施步骤如下:
一, 提交具体需要实施的自动化测试用例
在我们了解了具体的众筹网的业务后,我们提取出核心业务如:登录,注册,查看项目,支持项目,跟进项目进度,个人中心相关操作等。
二, 设计自动化测试架构
根据我们上面讲解的思路,我们创建一个工程,如:MobAutoZhongChouPro,并在工程下创建四个package,分别如下:
CommonFunctions:公用函数层,存放工程用到的公用函数。
TestCases:测试用例层,存放测试用例脚本。
TestData:测试数据层,存放测试用例对应的测试数据。
TestSuites:测试用例集层,存放使用不同场景的测试用例集文件。
创建完成后,如图6.6.1所示:
图6.6.1 设计自动化测试工程架构
三, 通过用例完善工程。
在创建完工程架构后,就要填写相应的代码。首先要先编写通用函数,我们做的是移动自动化测试的,所有的测试用例需要做的操作就是打开手机上面的App,如果没有这个App则先安装。
(1) 封装打开app的函数,我们创建通用类CommonFunctions,在里面创建函数setup(),注意是小写的,要和unittest的setUp()区分开。
def setup(self):
'''
打开App并且滑过欢迎页
'''
global DRIVER
desired_caps={}
desired_caps['device'] = 'android'
desired_caps['platformName']='Android'
desired_caps['browserName']=''
desired_caps['version']='4.4.2'
desired_caps['deviceName']='HM_2A' #小米
desired_caps['app'] = PATH('../../app/zhongchou.apk') DRIVER=webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
time.sleep(5)
#2.滑屏
DRIVER.swipe(600, 660, 10, 660, 1000)
time.sleep(1)
DRIVER.swipe(600, 660, 10, 660, 1000)
time.sleep(1)
DRIVER.swipe(600, 660, 10, 660, 1000)
time.sleep(2)
DRIVER.find_element_by_id("com.subject.zhongchou:id/bt").click()
time.sleep(2)
DRIVER.tap([(600,600)], 10)
time.sleep(2)
在这个函数中,我们先是检测手机上有没有安装App,如果没有则安装 ,如果有则打开。众筹的App打开的时候有一个欢迎页,所以要增加滑过欢迎页,进入主页的操作。
(2) 分析具体的测试用例。下面我们开始编写具体的测试用例,以登录为例,具体操作步骤如下:
Ø 打开app,滑过欢迎页进入主页
Ø 单击“我的”按钮,进入下一页
Ø 单击“马上登录”按钮,进入登录页
Ø 输入用户名和密码,单击登录按钮登录
Ø 检测登录是否成功。
分析测试用例:
A,第一步操作我们已经封装了,所以可以直接调用。
B,登录具体的操作2-3可以封装成一个函数,因为我们在以后的很多用例中都可以用到。
C,第4点检测工作,我们需要放到具体测试用例文件中。
封装登录操作函数,login(username,psd),具体代码如下:
def login(self,username,psd):
'''
登录
@param username: 用户名
@param psd:密码
'''
#单击“我的”按钮
elems=DRIVER.find_elements_by_class_name("android.widget.CheckedTextView")
elems[3].click()
time.sleep(2)
#单击“马上登录”按钮
DRIVER.find_element_by_id("com.subject.zhongchou:id/login_now_tv").click()
time.sleep(2)
#输入用户名
elusername= DRIVER.find_element_by_id('com.subject.zhongchou:id/loginnumber_phones')
elusername.click()
DRIVER.tap([(60,1220)])
elusername.send_keys(username)
#密码elpsd=DRIVER.find_element_by_id('com.subject.zhongchou:id/loginnumber_password')
elpsd.click()
elpsd.send_keys(psd)
#单击登录按钮
DRIVER.find_element_by_id("com.subject.zhongchou:id/go_numberlogin").click()
time.sleep(5)
通过调用这个函数,我们就完成了登录操作,在登录测试用例中我们需要检测登录是否成功,其他的用例中就不用检测登录,直接调用就可以。
在检测登录是否成功的时候,首先要获取用户昵称。根据元素获取显示内容,这个不仅在此处用,还需要其他的地方用,所以我们也封装出一个公用函数出来。
def gettext(self,method,loc,index=0):
'''
通过元素定位获取元素文本
@param method:标识定位方法
@param loc:元素标识
@param index:下标
'''
if method=="id":
elems=DRIVER.find_elements_by_id(loc)
if method=="class":
elems=DRIVER.find_elements_by_class_name(loc)
if method=="xpath":
elems=DRIVER.find_elements_by_xpath(loc)
return elems[index].text
(3) 组织测试数据。通过上面我们对测试用例操作的抽取,已经封装好了相关的逻辑操作,接下来我们组织测试数据。在testdata下创建loginTest.xml文件,具体的内容如下:
<?xml version="1.0" encoding="UTF-8"?> <testdata> <login name="登录测试数据"> <user>183****8905</user> <psd>a0****0</psd> <nickid>com.subject.zhongchou:id/name_tv<nickid> <nickname>潜龙9527<nickname> </login> </testdata>
我们把用户名和密码,以及获取昵称的路径和昵称都写到了这个数据文件中,这样如果我们被测试对象有变化的时候,只需要修改这个数据文件即可。
现在问题来了,我们有了xml组织的数据文件,怎么把数据读取出来呢?所以我们需要在CommonFunction包里添加数据读取操作类,DataOperations.py,具体内容如下:
import sys
import os
from xml.dom import minidom
global DOC,CONN
class DataOperations(object):
'''
数据读取相关操作
'''
def __init__(self,filename):
'''
初始化xml文档
'''
global DOC,CONN
#个人调试读取路径
DOC = minidom.parse("../TestData/"+filename)
#jenkins读取数据路径
#DOC = minidom.parse(os.getcwd()+"\\src\\TestData\\"+filename)
def readxml(self,tagnamefirst,tagNamesecond):
'''
从指定的文件中中读取指定节点的值
@param tagnamefirst:起始节点的名称,如:project
@param num:取与起始节点相同的第num个节点
@param tagNamesecond: 起始节点下的二级节点
@return: 返回二级节点的值
'''
root = DOC.documentElement
message=root.getElementsByTagName_r(tagnamefirst)[0]
return message.getElementsByTagName_r(tagNamesecond)[0].childNodes[0].nodeValue
(4) 组织测试用例。我们封装了具体的测试操作,而且又组织了测试数据,现在我们需要编写具体的测试用例函数,读取测试数据,调用公用函数,完成我们具体的测试用例。
在testcases包中创建测试用例脚本文件loginTest.py,根据我们的用例具体操作组织代码。内容如下:
#-*- coding: UTF-8 -*-
import unittest
import time
from appium import webdriver
from CommonFunctions.CommonFunctions import CommonFunctions
from CommonFunctions.DataOperations import DataOperations
class LoginTest(unittest.TestCase):
'''
测试登录功能
'''
def setUp(self):
CommonFunctions().setup()
def test_login(self):
#测试登录,正确的用户名和密码
dr=DataOperations("LoginTest.xml")
CommonFunctions().login(dr.readxml("login", "user"), dr.readxml("login", "psd"))
self.assertEqual(dr.readxml("login", "nickname"), CommonFunctions().gettext("id",dr.readxml("login", "nickid")))
if __name__ == '__main__':
unittest.main()
通过上面的代码,我们就可以组织将通用函数和测试数据结合起来,完成我们登录的测试操作。
(5)运行测试用例。
启动Appium服务端,将手机链接到电脑,通过adb devices –l查看是否链接成功。然后,右击我们的loginTest.py文件,选择“Run as”à”Python Run”即可运行。
此时appium服务端会有日志输出,并且手机会按我们预设的操作步骤进行执行,最后根据我们的判断来设置能否执行成功。
(6)编写测试用例集。
通过上面的五个步骤,我们可以不断地完善我们的自动化测试工程。在编写一个新的测试用例的时候,先看一下能否用到原来的公用函数 ,如果能,直接调用。如果不能,编写新的测试函数或是修改原来的测试函数。然后不断地增加测试用例文件和测试数据文件,我们的测试工程就会变得越来越庞大。此时就需要组织测试用例,我们是通过TestSuite来组织测试用例的。
在TestSuites文件夹下创建测试用例集文件,如OnlineTestSuite.py,其内容如下:
#-*- coding: UTF-8 -*-
'''
Created on 2015-12-18
@author: 58
'''
import unittest
import sys
import os
sys.path.append("..")
sys.path.append(os.getcwd()+"/src/")
from TestCases.LoginTest import LoginTest
class OnlineTestSuite():
def test(self):
if __name__ == "__main__":
#构造测试集
suite = unittest.TestSuite()
suite.addTest(LoginTest('test_login'))
……
runner = unittest.TextTestRunner()
result=runner.run(suite)
if __name__ == '__main__':
OnlineTestSuite().test()
我们可以将所有的需要执行的测试用例都按上面的方法添加到这个suite文件中,如果我们要执行这些测试用例直接运行这个文件即可。
6.7 本章小结
本章我们从整个流程介绍了移动自动化测试工程应该如何实施,并以众筹网为例,以登录测试用例为主来介绍如何搭建自动化测试框架,如何向框架里写代码?以实例来协调各个层次,达成我们的具体的测试用例编写,测试用例组织等工作。通过本章的学习,加上前五章的具体内容的介绍,你应该可以从零开始完成自己的移动自动化测试工程了。下面的章节,我们将介绍,如何将我们的自动化测试工程应用到实处,实现持续化集成。