在前段时间, 分享了几篇关于 appium 基础的博文, 再加上期间也有讲到 unittest 测试框架, 所以今天就来一个专题, 在 appium+python 实现的线性代码基础上, 引入 unittest 框架, 使代码更简洁.
之前的博客, 可以见以下链接快速阅读:
基于 Python 的 Appium 环境搭建合集
Genymotion 模拟器的安装及脚本制作
Appium Python API 中文版
Appium-Server 与 Appium-Desktop 的区别
单元测试框架 Uinttest 一文详解
在以上博文中, 代码示例, 很多只是个线性脚本, 没有太多的实用之处, 用来写个 demo 还是可以, 但实际运用到产品中, 就不行了. 脚本还是得引用框架, 这样看起来, 代码就不会那么乱, 更有逻辑性, 便于维护.
好了, 进入正题, 对 unittest 以及 appium 还不熟悉的, 可以先阅读如上的博文了解, 此篇文中, 就不赘述了.
unittest 代码优化一
优化逻辑:
1将启用服务字段放到初始化当中
2将输入账号, 输入密码, 获取当前 activity 的操作封装成一个个函数
3在用例中去调用需要执行的函数
示例代码如下:
- 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 True
- def setUp(self):
- # 在是 python3.x 中, 如果在这里初始化 driver , 因为 3.x 版本 unittestbasic1 运行机制不同, 会导致用力失败时截图失败
- self.driver.implicitly_wait(30)
- self.imgs = []
- self.addCleanup(self.cleanup)
- def cleanup(self):
- pass
- def 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 代码优化二
优化逻辑:
1将启用服务字段放到初始化当中
2将输入账号, 输入密码, 获取当前 activity 的操作封装成一个个函数, 并将数据参数做成形参
3在用例中去调用需要执行的函数并入参
示例代码如下:
- 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 True
- def setUp(self):
- # 在是 python3.x 中, 如果在这里初始化 driver , 因为 3.x 版本 unittestbasic1 运行机制不同, 会导致用力失败时截图失败
- self.driver.implicitly_wait(30)
- self.imgs = []
- self.addCleanup(self.cleanup)
- def cleanup(self):
- pass
- def 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 模式, 那代码的健壮性就更高了, 以后有时间再出类似博文.
本文仅代表作者观点, 系作者 @温一壶清酒发表.
来源: https://www.cnblogs.com/hong-fithing/p/11733788.html