实现思路:(以企业微信的通过手动输入添加成员为例)
PO思想六大原则(官网:https://martinfowler.com/bliki/PageObject.html):
(引用自:https://www.cnblogs.com/zxycb/p/13756662.html):
1. 公共的方法代表页面的服务
2. 不要暴露页面细节
3. 不要把断言和操作细节混用
4. 方法可以return到新打开的页面
5. 不要封装页面所有元素(用到哪些封装哪些)
6. 相同的行为会产生不同的结果,可以封装不同的方法
具体分析:
原则一:要封装页面中的功能或服务,比如点击页面元素,可以进入到新的页面,则可为这个服务封装方法"进入新页面"
原则二:封装细节,对外只提供方法名(或者接口)
原则三:封装的操作细节中不要使用断言,把断言放到单独的模块中,比如:testcase
原则四:点击一个按钮会开启新的页面,可以用return方法链式跳转,比如return MainPage()表示跳转到主页
原则五:只为页面中重要的元素进行PO设计,舍弃不重要的内容;用到哪些再封装哪些
原则六:一个动作可能产生不同结果,比如点击按钮后,可能成功,也可能失败,为两种结果封装两个方法:click_success和click_error
1、梳理需要实现自动化的测试用例。
根据策略将需要实现的用例梳理出来,找其中一个先实现。
有时间可以建模,可以清晰页面的跳转关系(熟练了就没有必要输出了),类似如下这种
2、构造PO模型
创建包结构:base、page、testcase
根据用例涉及到的页面,创建页面相关的类和方法,具体的实现内容可以先跳过。
例如:base中的app.py
查看代码
class App:
def start(self):
"""启动app"""
return self # 由于启动后要跳转到首页,所以这里返回self,便于调用into_main_page方法
def stop(self):
"""停止app"""
pass
def restart(self):
"""重启app"""
pass
def into_main_page(self):
"""进入首页"""
return MainPage()
例如:page中的main_page.py
查看代码
class MainPage:
def goto_address_list(self):
"""跳转到通讯录页面"""
return AddressListPage()
就这样用到那个就创建哪个页面类,链式的就把所有的都创建了,创建后的目录:
3、编写测试用例
根据业务逻辑编写、链式调用、做结果校验,简单的调通,先把架子打起来,不用写细节
例如:testcase中的test_add_member.py
查看代码
class TestAddMember:
def setup(self):
self.app = App()
self.main = self.app.start().into_main_page()
def teardown(self):
self.app.stop()
def test_add_member_manual(self):
"""测试手动添输入加用例"""
result = self.main.goto_address_list() \
.goto_add_member_list() \
.goto_add_member_manual() \
.save() \
.get_add_member_result()
# todo 当前返回的是True,待完善后重新写断言
assert result
4、填充各方法中的具体实现
- 启动app
- driver实例的传递
- 补充细节操作
5、优化用例
- 封装样板代码,提取页面元素
- driver的复用:考虑每个class设置一次;每个case结束关闭app然后再次启动(这样不用每个case操作后都要返回到首页,缺点是重复启动浪费时间)
思路就是:让driver默认值为None首次肯定为None则首次一定会初始化;后面case执行时如果服务挂掉也会重新初始化;然后case之间只是关闭app,driver并不为None,就可以复用driver。
- 初始化的desire_capability数据可以考虑放到配置文件中或者数据库,便于维护、管理。
6、并发执行
思路:当有多台机器时,执行pytest时需要配置appium client与server之间的端口,指定设备uuid
- desire_capability中添加udid,并动态获取,指定设备;链接的端口改为动态获取
-
udid = os.getenv("uuid") port = os.getenv("port")
-
"uuid": udid,
-
self.driver = webdriver.Remote(f"http://localhost:{port}/wd/hub", desire_cap)
-
- 另外开启一个cmd窗口,再启动server并指定端口:appium –session-override –p 4725 (端口号默认是4723,自己也可以指定一个端口)
- 执行时指定参数:
- mac系统:udid="127.0.0.1:7555" port=4723 pytest test_add_member.py
- windows:set udid="127.0.0.1:7555",回车后再输入 set port="4723",回车后再输入 pytest test_add_member.py
7、继续下一条用例输出
demo地址:https://gitee.com/fengyudeleishui/autotest/tree/master/homework/task_app
z