基于appium实现的线性代码引用unittest单元测试框架

当筵意气临九霄,星离雨散不终朝。这篇文章主要讲述基于appium实现的线性代码引用unittest单元测试框架相关的知识,希望能为你提供帮助。
在前段时间,分享了几篇关于appium基础的博文,再加上期间也有讲到unittest测试框架,所以今天就来一个专题,在appium+python实现的线性代码基础上,引入unittest框架,使代码更简洁。
之前的博客,可以见以下链接快速阅读:
基于Python的Appium环境搭建合集
Genymotion模拟器的安装及脚本制作
Appium Python API 中文版
Appium-Server与Appium-Desktop的区别
【基于appium实现的线性代码引用unittest单元测试框架】单元测试框架Uinttest一文详解
在以上博文中,代码示例,很多只是个线性脚本,没有太多的实用之处,用来写个demo还是可以,但实际运用到产品中,就不行了。脚本还是得引用框架,这样看起来,代码就不会那么乱,更有逻辑性,便于维护。
好了,进入正题,对unittest以及appium还不熟悉的,可以先阅读如上的博文了解,此篇文中,就不赘述了。
unittest代码优化一优化逻辑:
①将启用服务字段放到初始化当中
②将输入账号、输入密码、获取当前activity的操作封装成一个个函数
③在用例中去调用需要执行的函数
示例代码如下:

import selenium import time from appium import webdriver from selenium.webdriver.support.ui import WebDriverWait import unittest\'\'\' @author: wenyihuqingjiu @project: appiumcode @file: test_login.py @time: 2019-10-20 22:11 @desc: \'\'\'print(\'selenium version = \', selenium.__version__)def input_account(self): account = self.driver.find_element_by_id(\'id/rel_content\') account.find_element_by_id(\'id/edit_acount\') print("定位输入框") self.driver.press_keycode(61) print("换行操作") account.send_keys(\'\') print("账号输入完毕") time.sleep(2)def current(self): ac = self.driver.current_activity print(\'当前activity:\' + ac)def input_password(self): # genymotion只需要一次换行 self.driver.press_keycode(61) print("换行操作") password = self.driver.find_element_by_id(\'id/rel_content\') password.find_element_by_id(\'id/edit_pass\') print("定位输入框") password.send_keys(\'\') print("输入密码") self.driver.find_element_by_xpath(\'//android.widget.TextView[@text="登 录"]\').click() print("点击登录") time.sleep(5) print(\'登录成功\')class case_01(unittest.TestCase): @classmethod def setUpClass(cls):desired_caps = {\'platformName\': \'Android\', \'platformVersion\': \'4.4.4\', \'deviceName\': \'S5\', \'appPackage\': \'\', # 非首次登录的activity \'appActivity\': \'.ui.login.view.LoginActivity\', \'udid\': \'192.168.66.101:5555\', \'noReset\': \'true\',} cls.driver = webdriver.Remote(\'http://192.168.1.101:4723/wd/hub\', desired_caps) print("服务启动成功")@classmethod def tearDownClass(cls): cls.driver.quit()def add_img(self): self.imgs.append(self.driver.get_screenshot_as_base64()) return Truedef setUp(self): # 在是python3.x 中,如果在这里初始化driver ,因为3.x版本 unittestbasic1 运行机制不同,会导致用力失败时截图失败 self.driver.implicitly_wait(30) self.imgs = [] self.addCleanup(self.cleanup)def cleanup(self): passdef test_login01(self): input_account(self) current(self) input_password(self)if __name__ == "__main__": suites = unittest.TestSuite() suites.addTest(case_01("test_login01")) runner = unittest.TextTestRunner(verbosity=2) runner.run(suites)

unittest代码优化二优化逻辑:
①将启用服务字段放到初始化当中
②将输入账号、输入密码、获取当前activity的操作封装成一个个函数,并将数据参数做成形参
③在用例中去调用需要执行的函数并入参
示例代码如下:
import selenium import time from appium import webdriver from selenium.webdriver.support.ui import WebDriverWait import unittest\'\'\' @author: wenyihuqingjiu @project: appiumcode @file: test_login.py @time: 2019-10-20 22:11 @desc: \'\'\'print(\'selenium version = \', selenium.__version__)def input_account(self, username): account = self.driver.find_element_by_id(\'id/rel_content\') account.find_element_by_id(\'id/edit_acount\') print("定位输入框") self.driver.press_keycode(61) print("换行操作") account.send_keys(username) print("账号输入完毕") time.sleep(2)def current(self): ac = self.driver.current_activity print(\'当前activity:\' + ac)def input_password(self, send_password): # genymotion只需要一次换行 self.driver.press_keycode(61) print("换行操作") password = self.driver.find_element_by_id(\'id/rel_content\') password.find_element_by_id(\'id/edit_pass\') print("定位输入框") password.send_keys(send_password) print("输入密码") self.driver.find_element_by_xpath(\'//android.widget.TextView[@text="登 录"]\').click() print("点击登录") time.sleep(5) print(\'登录成功\')class case_01(unittest.TestCase): @classmethod def setUpClass(cls):desired_caps = {\'platformName\': \'Android\', \'platformVersion\': \'4.4.4\', \'deviceName\': \'S5\', \'appPackage\': \'\', # 非首次登录的activity \'appActivity\': \'.ui.login.view.LoginActivity\', \'udid\': \'192.168.66.101:5555\', \'noReset\': \'true\',} cls.driver = webdriver.Remote(\'http://192.168.1.101:4723/wd/hub\', desired_caps) print("服务启动成功")@classmethod def tearDownClass(cls): cls.driver.quit()def add_img(self): self.imgs.append(self.driver.get_screenshot_as_base64()) return Truedef setUp(self): # 在是python3.x 中,如果在这里初始化driver ,因为3.x版本 unittestbasic1 运行机制不同,会导致用力失败时截图失败 self.driver.implicitly_wait(30) self.imgs = [] self.addCleanup(self.cleanup)def cleanup(self): passdef test_login01(self): # 正常登录 input_account(self, "") current(self) input_password(self, "")def test_login02(self): # 异常登录 input_account(self, "") current(self) input_password(self, "")if __name__ == "__main__": suites = unittest.TestSuite() suites.addTest(case_01("test_login01")) suites.addTest(case_01("test_login02")) runner = unittest.TextTestRunner(verbosity=2) runner.run(suites)

通过上述代码可看出,使用更方便了,可以满足正向/反向的用例设计了,是不是很简单。
代码可扩展性还有很多,在unittest基础上,再引入PO模式,那代码的健壮性就更高了,以后有时间再出类似博文。

    推荐阅读