第六章 移动自动化测试工程的开展(下)

                  --------手机自动化之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(),注意是小写的,要和unittestsetUp()区分开。

 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 本章小结

    本章我们从整个流程介绍了移动自动化测试工程应该如何实施,并以众筹网为例,以登录测试用例为主来介绍如何搭建自动化测试框架,如何向框架里写代码?以实例来协调各个层次,达成我们的具体的测试用例编写,测试用例组织等工作。通过本章的学习,加上前五章的具体内容的介绍,你应该可以从零开始完成自己的移动自动化测试工程了。下面的章节,我们将介绍,如何将我们的自动化测试工程应用到实处,实现持续化集成。

 

posted @ 2016-01-11 18:15  潜龙9527  阅读(162)  评论(0编辑  收藏  举报