前言
在上一篇文章--Appium自动化(十三)引入ddt管理测试用例数据,由于代码的逐渐增加,原有的文件足够大,不利于维护,为了更好的维护呢,我们利用分层化的思想对于代码进行拆分,优化,便于后期的维护。
正文
我们对包进行拆分,先按照功能拆分,实现功能类型相同的放在一个包里。我们现在有根据包获取启动app,根据adb 获取设备信息,这些都可以放在common内。那么我们去创建一个common的包,其次我们还有用例的管理的包,我们可以叫做case包。我们还需要一个执行的文件,可以创建一个run.py。
那么接下来我们对于包内的文件进行按照函数的方式进行拆分,那么就可以分拆成 packageparse.py和adbtool.py。这是通用的,我们可以放在common目录内。我们的测试用例呢,可以按照现在的功能拆分成logintestcase.py,直接放在case的目录中。我们根据功能对代码进行最后的划分。整理后的packageparse.py代码如下
from androguard.core.bytecodes.apk import APK
def get_apkname(apk):
a = APK(apk, False, "r")
return a.get_package()
def get_apk_lautc(apk):
a = APK(apk, False, "r")
return a.get_main_activity()
adbtool.py代码如下
import os
def get_devices() -> list:
all_devices = []
cmd = "adb devices"
reslut = os.popen(cmd).readlines()[1:]
for item in reslut:
if item != "\n":
all_devices.append(str(item).split("\t")[0])
return all_devices
def getPlatForm(dev: str) -> str:
cmd = 'adb -s {} shell getprop ro.build.version.release'.format(dev)
reslut = os.popen(cmd).readlines()[0]
return str(reslut).split("\n")[0]
def isinstallapk(packname: str, devname: str) -> bool:
cmd = "adb -s {} shell pm list packages -3".format(devname)
reslut = os.popen(cmd).readlines()
all_apkname = []
for i in reslut:
apkname = str(i).split('\n')[0].split(":")[1]
all_apkname.append(apkname)
if packname in all_apkname:
return True
return False
def uninstallapk(packname: str, devname: str) -> bool:
cmd = "adb -s {} shell pm list packages -3".format(devname)
reslut = os.popen(cmd).readlines()
all_apkname = []
for i in reslut:
apkname = str(i).split('\n')[0].split(":")[1]
all_apkname.append(apkname)
if packname in all_apkname:
cmd = 'adb -s %s uninstall %s ' % (devname, packname)
os.system(cmd)
return True
return False
def installapk(paknamepath: str, devname: str) -> bool:
cmd = 'adb -s %s install %s' % (devname, paknamepath)
os.system(cmd)
return True
logintestcase.py代码如下
from time import sleep
from common.adbtool import *
from common.packageparse import *
import unittest,ddt
from appium import webdriver
data=[{'username':"name",'password':"123456"},{'username':"shibai",'password':"123456"}]
apk_path = "/Users/lileilei/Downloads/iBiliPlayer-bili.apk"
@ddt.ddt
class testCase(unittest.TestCase):
def setUp(self) -> None:
packname = get_apkname(apk_path)
dev = get_devices()[0]
is_first_install = False
# 1.判断是否安装app
is_install = isinstallapk(packname, dev)
if is_install is False:
# 2.如果没有安装,则安装
installapk(apk_path, dev)
is_first_install = True
# 3.启动apk测试
apkname = get_apkname(apk_path)
launcheractivity = get_apk_lautc(apk_path)
desired_caps = {
'platformName': 'Android',
'deviceName': dev, # adb deivces
'platformVersion': getPlatForm(dev), # 从设置中可以获取
'appPackage': apkname, # 包名
'appActivity': launcheractivity, # apk的launcherActivity
# 'skipServerInstallation': True
}
self.driver = webdriver.Remote('http://0.0.0.0:4723/wd/hub', desired_caps)
sleep(10)
# 启动同意用户协议
self.driver.find_element_by_id("tv.danmaku.bili:id/agree").click()
if is_first_install:
# 首次安装需要加载文件
sleep(50)
sleep(10)
self.driver.find_element_by_id("tv.danmaku.bili:id/avatar_layout").click()
sleep(5)
self.driver.find_element_by_xpath("//*[@text='登录']").click()
def tearDown(self) -> None:
self.driver.close()
@ddt.data(*data)
def testlogin(self,data):
username = self.driver.find_element_by_id('tv.danmaku.bili:id/username')
username.clear()
username.send_keys(data['username'])
password = self.driver.find_element_by_id('tv.danmaku.bili:id/passport_tag')
password.clear()
password.send_keys(data['passowrd'])
login = self.driver.find_element_by_id('tv.danmaku.bili:id/btn_login')
login.click()
try:
self.driver.find_element_by_id('tv.danmaku.bili:id/btn_login')
self.assertTrue(False,msg="测试失败")
except:
self.assertTrue(True,msg="测试成功")
run.py代码如下
import unittest as un
if __name__ =="__main__":
suite = un.TestSuite()
suite.addTests(un.TestLoader().loadTestsFromName("case.logintestcase.testCase"))
rune = un.TextTestRunner()
rune.run(suite)
最后的目录如下:
这样我们就对代码利用分层的想法对于代码进行做了简单拆分,拆分后,代码目录,代码片段功能更加清晰明了。后续还会持续的对于代码进行优化。