Appium 让 Appium 项目稍微优雅点 [Node 版]

CNO · 2017年01月19日 · 最后由 Manny 回复于 2017年05月03日 · 916 次阅读

前段时间用的UI自动化测试框架主要是两个:Macaca和Appium。后来基于了非常多的原因,还是用了大家都用的Appium(这家伙对iOS10支持非常不好)。如果你刚接触这两个包装着Mocha的测试框架,而且想用Node去写整个测试框架,都会发现它们共同的毛病:慢,卡,不稳定,代码不方便阅读等等。这些是很多原因造成的,比如之前用Macaca写登录脚本是一长串Promise。

测试用例写出来后,在模拟器上跑着还不稳定,上一次用例通过了,这一次用例失败了,加上测试速度,格外让人蛋疼。后来经过大神指点迷津,在书写方式和架构上面进行了修改,整个项目看起来清爽不少。

一番改造后,抛弃了Promise,使用Generator和yield,最后的要点就是人们常说的“高耦合,低内聚”。

yiewd

Appium下编写测试用例遵循WebDriver协议,Node下可以用wd,而在yiewd在wd外面包了一层,这样你就可以编写更加直观的代码了,解决异步编程问题不是用Promise,而是用Generator。

项目架构

项目结构我改了很多遍,效果都不理想:每个测试用例间如果有相互依赖,一个挂了,下面的接着挂了。然后参考这篇文章,对项目进行了改造:
|----app·····················放置各个版本app
|----src
|----|----cases············测试用例
|----|----screen···········Screen类
|----|----util·················工具类
|----cap.js·················环境配置
|----client.js
|----dev.js

screen:这个里面放置的是Screen类,主要的场景都可以写一个Screen类,Screen类上包含这个场景上的UI操作,比如登陆、后退、下拉刷新、下滑、绘制手势等。例如一个APP开始页面,包含关闭弹框,滑动窗口等功能。

import {swipe} from '../util/yiewdAction';
export default class StartScreen {
constructor(driver, context) {
this.driver = driver;
this.context = context;
}

*closeAlert() {
const driver = this.driver;
const element = yield driver.elementByNameIfExists('closeActivity');
if (element) {
yield element.click();
}
yield driver.sleep(3000);
}

*slideScreen() {
const driver = this.driver;
yield swipe(driver, 300, 300, -300, 0, 500);
yield driver.sleep(500);
yield swipe(driver, 300, 300, -300, 0, 500);
yield driver.sleep(500);
yield swipe(driver, 300, 300, -300, 0, 500);
}

*openApp() {
yield this.driver.waitForElementByClassName('Button', 3000, 100).click();
yield this.driver.sleep(5000);
}
}

cases:有了Screen类,我们只需要关心测试用例的编写了,从开启APP到进入待测页面,可以用Screen类的UI操作,不需要重复编写,例如:

import '../util/should';
import InitScreen from '../screen/InitScreen';
import StartScreen from '../screen/StartScreen';
import LoginScreen from '../screen/LoginScreen';
import MainScreen from '../screen/MainScreen';
import HomeIndexScreen from '../screen/HomeIndexScreen';
import HomeProductFixedScreen from '../screen/HomeProductFixedScreen';
import {env, nativeContext} from '../caps';

export default function freeList(driver, done) {
const initScreen = new InitScreen(driver, nativeContext);
const startScreen = new StartScreen(driver, nativeContext);
const loginScreen = new LoginScreen(driver, nativeContext);
const mainScreen = new MainScreen(driver, nativeContext);

return driver.run(function *() {
yield *initScreen.acceptAlert();
yield *initScreen.chooseEnv(env);
yield *startScreen.closeAlert();
yield *startScreen.slideScreen();
yield *startScreen.openApp();
yield *mainScreen.closeActivity();

let contexts = yield driver.contexts();
const homeIndexScreen = new HomeIndexScreen(driver, contexts[contexts.length - 1]);
yield *homeIndexScreen.goLogin();
yield *loginScreen.login();
yield *loginScreen.drawGesture();
yield *mainScreen.goLiCai();

//...
done();
});
}

不需要重复写一些操作,进入到待测页面有Screen类提供的一条龙服务。

改造下来,代码看着舒服多了,而且没有用例这次通过,下次挂的情况。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 9 条回复 时间 点赞

哈,用nodejs写,挺少见的,不过编译器挺好的,红红绿绿的😍

—— 来自TesterHome官方 安卓客户端

CNO #2 · 2017年01月19日 作者

#1楼 @hu_qingen 编辑器是Atom

#2楼 @Cononico 分享下你的插件列表呗

#3楼 @seveniruby 你有参加那个 测试微服务平台的么

标题有一个地方写错了 yield被你写成了 yiewd

CNO #8 · 2017年01月22日 作者

#3楼 @seveniruby
都是常用的插件:

  • git-plus
  • linter-eslint Atom颜值就是高😀

hello,能吧你的yiewdAction的代码给看一下么。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册