Androidのビルドに--Appium +のpython +ジェンキンス自動テストフレームワークのテストを自動化

ディレクトリ

 

総合的な知識の枠組み

(Windowsの場合)環境の準備

appiumインストールして使用

ADBデバイスはDEVICENAMEによって得ることができます

appPackageとappActivity取得:接続電話ドス入力

 Appiumと導入関連PycharmプラグAppium-Pythonのクライアント----パイソン

 ​

 HTMLTestReportCN ----テストレポートを生成します

改訂されたテストコード:

テストケース2:FirstTest

テストケース2:SecondTest

主なテスト:テストパッケージに複数のユニットテストを使用して

データ構成データ分離YAML ----

ログ収集

ログ構成

----コードパッケージデザインモードのPageObject

アプリのスタートアップコンフィギュレーションパッケージ 

パッケージのベースクラス:baseview 

 

一般公衆クラスパッケージ 

Windowsのツールは、バットのテストケースを実行するバッチファイルで使用されます

Pythonの開始Appium

ジェンキンス継続的インテグレーション


総合的な知識の枠組み

(Windowsの場合)環境の準備

1.jdk1.8.0 (64位)
2.android-sdk(直接下载安卓studio就都有了)
3.python:3.7
4.Appium-windows-1.15.1
5.Node.js
//以上安装并配置好环境变量
6.Appium-Python-Client
7.pycharm(用于编写脚本)
8.HTMLTestReportCN(用于生成测试报告)
//以下可选
yaml
//以下两个是为了定时执行用例和发送测试报告——可不用安装
9.Tomcat
10.Jenkins 

appiumインストールして使用

公式ウェブサイトのアドレス:https://github.com/appium/appium-desktop/releases/tag/v1.15.1

あなたはダウンロードしてインストールすることができます

ADBデバイスはDEVICENAMEによって得ることができます

 

appPackageとappActivity取得:接続電話ドス入力

adb shell dumpsys window | findstr mCurrentFocus

 Appiumと導入関連PycharmプラグAppium-Pythonのクライアント----パイソン

 

 HTMLTestReportCN ----テストレポートを生成します

ダウンロードのpythonとディレクトリlibフォルダに置か

公式サイト:https://github.com/findyou/HTMLTestRunnerCN

HTMLTestReportCN両方を使用して、プラグインを拡張ユニットテストであります

改訂されたテストコード:

テストケース2:FirstTest

# This sample code uses the Appium python client
# pip install Appium-Python-Client
# Then you can paste this into a file and simply run with Python

from appium import webdriver
import time
import unittest
from HTMLTestRunnerCN import HTMLTestReportCN

caps = {}
caps["platformName"] = "Android"
caps["platformVersion"] = "10"
caps["deviceName"] = "R28M3126C2W"
caps["appPackage"] = "cn.cntv"
caps["appActivity"] = "cn.cntv.ui.activity.SplashActivity"


class FirstTest(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)

    def tearDown(self) -> None:
        self.driver.quit()

    def test_start(self):
        el1 = self.driver.find_element_by_id("com.android.permissioncontroller:id/permission_allow_button")
        el1.click()
        time.sleep(10)
        el2 = self.driver.find_element_by_id("com.android.permissioncontroller:id/permission_allow_always_button")
        el2.click()
        time.sleep(10)
        el3 = self.driver.find_element_by_id("com.android.permissioncontroller:id/permission_allow_button")
        el3.click()
        time.sleep(10)
        el4 = self.driver.find_element_by_id("cn.cntv:id/agree")
        el4.click()
        time.sleep(10)
        el5 = self.driver.find_element_by_xpath(
            "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.HorizontalScrollView/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.TextView")
        el5.click()
        el6 = self.driver.find_element_by_xpath(
            "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.HorizontalScrollView/android.widget.LinearLayout/android.widget.LinearLayout[3]/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.TextView")
        el6.click()
        el7 = self.driver.find_element_by_xpath(
            "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.HorizontalScrollView/android.widget.LinearLayout/android.widget.LinearLayout[4]/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.TextView")
        el7.click()


if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(FirstTest)

    unittest.TextTestRunner().run(suite)

テストケース2:SecondTest

# This sample code uses the Appium python client
# pip install Appium-Python-Client
# Then you can paste this into a file and simply run with Python

from appium import webdriver
import time
import unittest

caps = {}
caps["platformName"] = "Android"
caps["platformVersion"] = "10"
caps["deviceName"] = "R28M3126C2W"
caps["appPackage"] = "cn.cntv.zongyichunwan"
caps["appActivity"] = "cn.cntv.ui.activity.SplashActivity"

#TestCase类,所有测试用例类继承的基本类
class SecondTest(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", caps)

    def tearDown(self) -> None:
        self.driver.quit()

    def test_start(self):
        el1 = self.driver.find_element_by_id("com.android.permissioncontroller:id/permission_allow_button")
        el1.click()
        time.sleep(10)
        el2 = self.driver.find_element_by_id("com.android.permissioncontroller:id/permission_allow_button")
        el2.click()
        time.sleep(10)
        el3 = self.driver.find_element_by_id("com.android.permissioncontroller:id/permission_allow_button")
        el3.click()
        time.sleep(10)
        el4 = self.driver.find_element_by_id("cn.cntv.zongyichunwan:id/dialog_like_ios_certain")
        el4.click()
        time.sleep(10)
        el5 = self.driver.find_element_by_id("cn.cntv.zongyichunwan:id/btnJump")
        el5.click()
        time.sleep(10)
        el6 = self.driver.find_element_by_xpath(
            "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.LinearLayout[1]/android.widget.HorizontalScrollView/android.widget.LinearLayout/android.support.v7.app.ActionBar.Tab[2]/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.TextView")
        el6.click()
        time.sleep(10)
        el7 = self.driver.find_element_by_xpath(
            "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.support.v4.view.ViewPager/android.widget.RelativeLayout/android.widget.ListView/android.widget.LinearLayout[1]/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.ImageView[2]")
        el7.click()
        time.sleep(10)
        self.driver.back()
        el8 = self.driver.find_element_by_xpath(
            "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.support.v4.view.ViewPager/android.widget.RelativeLayout/android.widget.ListView/android.widget.LinearLayout[1]/android.widget.LinearLayout/android.widget.TextView")
        el8.click()
        time.sleep(10)
        self.driver.back()


if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(SecondTest)
    unittest.TextTestRunner().run(suite)

 

主なテスト:テストパッケージに複数のユニットテストを使用して

# import os
# os.system("python ./FirstTest.py")
# os.system("python ./SecondTest.py")
import unittest
from FirstTest import FirstTest
from SecondTest import SecondTest
import HTMLTestRunnerCN

if __name__ == '__main__':
    suite = unittest.TestSuite()
    suite.addTests(unittest.TestLoader().loadTestsFromTestCase(FirstTest))
    suite.addTests(unittest.TestLoader().loadTestsFromTestCase(SecondTest))

    # 确定生成报告的路径
    filePath = 'D:\ReportCN.html'
    fp = open(filePath, 'wb')
    # 生成报告的Title,描述
    runner = HTMLTestRunnerCN.HTMLTestReportCN(stream=fp, title='自动化测试报告', description='详细测试用例结果', tester='jackron')
    runner.run(suite)

データ構成データ分離YAML ----

表1パラメータ設定:desired_caps.yaml

platformName: Android
platformVersion: 5.1.1
deviceName: 127.0.0.1:62025
app: C:\Users\Shuqing\Desktop\Appium software\chapter4\App\kaoyan3.1.0.apk
noReset: False
appPackage: com.tal.kaoyan
appActivity: com.tal.kaoyan.ui.activity.SplashActivity

Pythonのファイルには、データを読み取ります

rom appium import webdriver
import yaml

file=open('desired_caps.yaml','r')
data=yaml.load(file)

desired_caps={}
desired_caps['platformName']=data['platformName']

desired_caps['platformVersion']=data['platformVersion']
desired_caps['deviceName']=data['deviceName']

desired_caps['app']=data['app']
desired_caps['noReset']=data['noReset']

desired_caps['appPackage']=data['appPackage']
desired_caps['appActivity']=data['appActivity']

driver = webdriver.Remote('http://'+str(data['ip'])+':'+str(data['port'])+'/wd/hub', desired_caps)

 

ログ収集

レベル

ときに使用します

デバッグ

デバッグ情報が、それが最も詳細なログ情報です。

INFO

期待通りに物事が働くことを証明。

警告

(このような「フルディスク」など)いくつかの事故や問題が近い将来に起こるであろうがあったことを示しています。または適切にソフトウェアの仕事インチ

エラー

より深刻な問題のためには、ソフトウェアは、機能の一部を実行することはできません。

CRITICAL

ソフトウェアを実行し続けることができないことを示す重大なエラー、。

 ログ出力位置と出力形式を定義します

#导入logging模块
import logging

logging构成

logging模块包括logger,Handler,Filter,Formatter四个部分。

  • Logger 记录器,用于设置日志采集。
  • Handler 处理器,将日志记录发送至合适的路径。
  • Filter 过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。
  • Formatter 格式化器,指明了最终输出中日志的格式。

Formatter

使用Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S。

格式

描述

%(levelno)s

打印日志级别的数值

%(levelname)s

打印日志级别名称

%(pathname)s

打印当前执行程序的路径

%(filename)s

打印当前执行程序名称

%(funcName)s

打印日志的当前函数

%(lineno)d

打印日志的当前行号

%(asctime)s

打印日志的时间

%(thread)d

打印线程id

%(threadName)s

打印线程名称

%(process)d

打印进程ID

%(message)s

打印日志信息

 

 

logging.basicConfig(filename='runlog.log',level=logging.DEBUG,
                  format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')

PageObject设计模式----代码封装

封装App启动配置信息 

desired_caps.py

import yaml
import logging.config
from appium import webdriver


CON_LOG = '../log/log.conf'
logging.config.fileConfig(CON_LOG)
logging = logging.getLogger()


def appium_desired():

    stream = open('../yaml/desired_caps.yaml', 'r')
    data = yaml.load(stream)

    desired_caps={}
    desired_caps['platformName']=data['platformName']

    desired_caps['platformVersion']=data['platformVersion']
    desired_caps['deviceName']=data['deviceName']

    desired_caps['app']=data['app']
    desired_caps['noReset']=data['noReset']

    desired_caps['unicodeKeyboard']=data['unicodeKeyboard']
    desired_caps['resetKeyboard']=data['resetKeyboard']

    desired_caps['appPackage']=data['appPackage']
    desired_caps['appActivity']=data['appActivity']

    logging.info('start run app...')
    driver = webdriver.Remote('http://'+str(data['ip'])+':'+str(data['port'])+'/wd/hub', desired_caps)

    driver.implicitly_wait(8)
    return driver

if __name__ == '__main__':
    appium_desired()

封装基类:baseview 

class BaseView(object):
    def __init__(self,driver):
        self.driver=driver

    def find_element(self,*loc):
        return self.driver.find_element(*loc)

 

封装通用公共类 

common_fun.py

from appium_advance.page_object.baseView import BaseView
from selenium.common.exceptions import NoSuchElementException
import logging
from selenium.webdriver.common.by import By
from appium_advance.page_object.desired_caps import appium_desired

class Common(BaseView):

    cancelBtn=(By.ID,'android:id/button2')
    skipBtn=(By.ID,'com.tal.kaoyan:id/tv_skip')

    def check_cancelBtn(self):
        logging.info("============check_cancelBtn===============")

        try:
            element = self.driver.find_element(*self.cancelBtn)
        except NoSuchElementException:
            logging.info('update element is not found!')
        else:
            logging.info('click cancelBtn')
            element.click()

    def check_skipBtn(self):
        logging.info("==========check_skipBtn===========")
        try:
            element = self.driver.find_element(*self.skipBtn)
        except NoSuchElementException:
            logging.info('skipBtn element is not found!')
        else:
            logging.info('click skipBtn')
            element.click()

if __name__ == '__main__':

    driver=appium_desired()
    com=Common(driver)
    com.check_updateBtn()
    com.check_skipBtn()

Windows 中使用批量工具Bat文件运行测试用例

@echo off
appium
pause
@echo off
D:
cd D:\study\PycharmProjects\HelloTest
start python MainTest.py

Python 启动Appium

import subprocess
from time import ctime

def appium_start(host,port):
    '''启动appium server'''
    bootstrap_port = str(port + 1)
    cmd = 'start /b appium -a ' + host + ' -p ' + str(port) + ' -bp ' + str(bootstrap_port)

    print('%s at %s' %(cmd,ctime()))
    subprocess.Popen(cmd, shell=True,stdout=open('./appium_log/'+str(port)+'.log','a'),stderr=subprocess.STDOUT)


if __name__ == '__main__':
    host = '127.0.0.1'
    for i in range(2):
        port=4723+2*i
        appium_start(host,port)

Jenkins 持续集成

jenkins定时构建语法

* * * * *
(五颗星,中间用空格隔开)

第一个*表示分钟,取值0~59
第二个*表示小时,取值0~23
第三个*表示一个月的第几天,取值1~31
第四个*表示第几月,取值1~12
第五个*表示一周中的第几天,取值0~7,其中0和7代表的都是周日
每天下午下班前18点定时构建一次

0 18 * * *
每天早上8点构建一次

0 8 * * *
每30分钟构建一次:

H/30 * * * *

 

 

 

发布了58 篇原创文章 · 获赞 4 · 访问量 4万+

おすすめ

転載: blog.csdn.net/jackron2014/article/details/104063123