全部产品

功能测试

更新时间:2017-06-07 13:26:11   分享:   

本文将介绍如何编写iOS功能测试脚本。

如果你还不了解UI Automation框架,或者不知道如何搭建、使用测试环境,那么请先阅读入门教程。除此之外,我们还提供了视频教程,即使你没有太多的编程经验,也只需大约一个小时就能学会编写简单的脚本。

在开始前,你可以 点击这里 下载与本文相关的测试脚本和应用。

1. 常用操作

UI Automation提供了非常多的接口来模拟UI操作,如点击、双击、双指缩放、拖曳等。

  • 单击。根据输入的绝对坐标点击屏幕。

    1. UIATarget.localTarget().tap({x:100, y:200});
  • 双击。根据输入的绝对坐标双击屏幕。

    1. UIATarget.localTarget().doubleTap({x:100, y:200});
  • 拉伸。模拟双指拉伸操作,第一个坐标点是起点,第二个坐标点是终点,最后一个参数是持续时间,单位为秒。

    1. UIATarget.localTarget().pinchOpenFromToForDuration({x:20, y:200}, {x:300, y:200}, 2);
  • 收缩。模拟双指收缩操作,第一个坐标点是起点,第二个坐标点是终点,最后一个参数是持续时间,单位为秒。

    1. UIATarget.localTarget().pinchCloseFromToForDuration({x:20, y:200}, {x:300, y:200}, 2);
  • 拖曳。模拟单指拖曳操作,第一个坐标点是起点,第二个坐标点是终点,最后一个参数是持续时间,单位为秒。

    1. UIATarget.localTarget().dragFromToForDuration({x:160, y:200}, {x:160, y:400}, 1);
  • 快速滑动。模拟单指快速滑动操作,第一个坐标点是起点,第二个坐标点是终点,与拖曳不同的是它没有时间参数,因为这个操作的速度很快。

    1. UIATarget.localTarget().flickFromTo({x:160, y:200}, {x:160, y:400});
  • 操作控件。除了根据绝对坐标进行操作,我们也可以先取得控件,然后进行相应的操作。当然,前提是这个控件是存在、有效且可见的。根据控件模拟操作要特别小心,因为有时候控件会被其他控件挡住,控件还没被加载出来,或者突然出现了弹框导致无法操作控件。

    1. var addButton = UIATarget.localTarget().frontMostApp().navigationBar().buttons()["Add"];
    2. if(addButton.isValid() && addButton.isVisible()){
    3. addButton.tap();
    4. }

如果你还不熟悉UI Automation的接口,那么录制功能将给你带来极大的便利,它会记录下你每次操作的步骤,生成相应的代码。使用方法见UI Automation教程。

2. 输出测试信息

我们希望编写的测试脚本能包含尽可能多的信息,以便于发现和分析可能出现的错误,而记录信息最简单有效的方式就是编写Case。下面看一个Case。

  1. var testName = "Module 001 Test";
  2. UIALogger.logStart(testName);
  3. //一些测试代码
  4. UIALogger.logPass(testName);

UIALogger是一个用于记录测试信息的工具类,我们调用它的logStart函数开始一项测试,并为测试项命名。因此,上面这个Case的名称就是”Module 001 Test”。在运行一段测试代码后,我们用logPass或logFail结束一项测试,记录测试结果(成功或失败)。

我们还可以用logMessage输出一些信息,类似于Java或C里的print。下面的Case就使用了logMessage,它用起来更自由、方便;并用captureScreenWithName截图,记录当时的状态。除此之外,UIALogger工具类还提供了更多的函数如logError, logWarning等。

  1. var testName = "Module 001 Test";
  2. UIALogger.logStart(testName);
  3. //一些测试代码
  4. UIALogger.logMessage("Starting Module 001 branch 2, validating input.");
  5. //截一张图,以给定的参数命名
  6. UIATarget.localTarget().captureScreenWithName("SS001-2_AddedIngredient");
  7. //更多测试代码
  8. UIALogger.logPass(testName);

3. 处理弹框

UI Automation提供了一个函数接口onAlert来处理弹框,当弹框出现时,将调用这个函数。接下来,我们编写一个非常简单的弹框处理函数。

  1. UIATarget.onAlert = function onAlert(alert) {
  2. var title = alert.name();
  3. UIALogger.logWarning("Alert with title '" + title + "' encountered.");
  4. // 返回false,使用默认处理方式
  5. return false;
  6. }

这个函数使用logWarning记录了弹框的名称,最后返回false,这将意味着点击默认按钮来关闭弹框。例如,当收到一条短信时,这个函数执行的操作是点击“关闭”按钮,从而关闭弹框。

如果弹框是app内部产生的,并且我们知道它的确切的名字,那么我们可以执行一些预期的操作,而不仅仅是关闭弹框。下面的代码为一个特定的弹框执行了点击“Continue”按钮的操作,并返回true,当然前提是我们确定“Continue”按钮是存在的。

  1. UIATarget.onAlert = function onAlert(alert) {
  2. var title = alert.name();
  3. UIALogger.logWarning("Alert with title '" + title + "' encountered.");
  4. if (title == "The Alert We Expected") {
  5. alert.buttons()["Continue"].tap();
  6. return true; //弹框已处理
  7. }
  8. //若返回false,则使用默认处理方式
  9. return false;
  10. }

4. 脚本示例

下面以“开源中国”app为例,编写一个登陆脚本。点击这里下载测试应用和脚本。

  1. var target = UIATarget.localTarget(); //UIATarget是最上层的类,表示真实设备或模拟器
  2. try{
  3. target.delay(3); //等待3秒,跳过开场动画
  4. UIALogger.logStart("test 1"); //第1个Case
  5. UIALogger.logMessage("开始第一个测试");
  6. var leftButton = target.frontMostApp().navigationBar().leftButton(); //取得导航栏的左侧按钮
  7. leftButton.tap(); //点击
  8. var techCell = target.frontMostApp().mainWindow().tableViews()[0].cells()["技术问答"]; //取得第一个cell
  9. if (techCell.isValid() && techCell.isVisible()) {
  10. UIALogger.logPass("find 技术问答");
  11. } else {
  12. UIALogger.logFail("cannot find 技术问答");
  13. }
  14. UIALogger.logStart("test 2"); //第2个Case
  15. UIALogger.logMessage("开始第二个测试");
  16. target.frontMostApp().mainWindow().buttons()[0].tap();
  17. target.delay(1); //等待动画结束
  18. target.frontMostApp().tabBar().buttons()["我"].tap();
  19. target.delay(1); //等待动画结束
  20. target.frontMostApp().mainWindow().tableViews()[1].cells()["消息"].tap();
  21. target.delay(1); //等待动画结束
  22. var loginButton = target.frontMostApp().mainWindow().buttons()["登录"];
  23. if(loginButton.isValid() && loginButton.isVisible()){ //如果登陆按钮有效且可见,则表示用户未登录,接下来尝试登陆
  24. var textField = target.frontMostApp().mainWindow().textFields()[0];
  25. var secureTextField = target.frontMostApp().mainWindow().secureTextFields()[0];
  26. textField.tap();
  27. textField.setValue("username"); //输入用户名
  28. target.delay(0.5);
  29. secureTextField.tap();
  30. secureTextField.setValue("password"); //输入密码
  31. target.delay(0.5);
  32. loginButton.tap();
  33. target.delay(3);
  34. if(loginButton.isValid() && loginButton.isVisible()){
  35. UIALogger.logFail("登陆失败");
  36. }else{
  37. UIALogger.logPass("登陆成功");
  38. }
  39. }else{
  40. UIALogger.logPass("用户已经登陆");
  41. }
  42. }catch(err){
  43. UIALogger.logError(err.toString());
  44. }
本文导读目录
本文导读目录
以上内容是否对您有帮助?