iOS自动化测试(原创)

安装部署

  在敏捷开发中,经常会听到TDD,BDD这些词语,对于如何进行测试驱动开发,不同的敏捷团队有不同的执行方式,针对于目前在iOS下的测试方案,我们搭建了iOS的自动化测试平台。

需要的安装文件(以下文件放到同一个目录下面,我的命名是setup_cucumber):

  1.Frank 源代码 (可以从https://github.com/moredip/Frank下载,该项目用于为本地iOS应用做自动化行为测试)

  2.必要的.gem档案 (如果有更新版本的.gem档,可以进行替换)

?
builder- 3 . 0 . 0 .gem
cucumber- 0 . 10 . 2 .gem
diff-lcs- 1 . 1 . 2 .gem
frank-cucumber- 0 . 6 . 1 .gem
gherkin- 2 . 3 . 7 .gem
json- 1 . 5 . 2 .gem
rack- 1 . 2 . 2 .gem
rspec- 2 . 5 . 0 .gem
rspec-core- 2 . 5 . 2 .gem
rspec-expectations- 2 . 5 . 0 .gem
rspec-mocks- 2 . 5 . 0 .gem
sim_launcher- 0 . 3 . 0 .gem
sinatra- 1 . 2 . 6 .gem
term-ansicolor- 1 . 0 . 5 .gem
tilt- 1 . 3 .gem

  3.install.sh

?
#!/bin/sh
sudo gem install *.gem

安装很简单,执行install.sh文件就可以了

  1.打开Terminal,进入setup_cucumber目录

  2.执行 ./install.sh

如果在安装过程出现问题,反复执行几次就可以了。

开始我们的自动化测试之旅

  1.建立一个新的 Target ,命名为 Demo-Frank

  2.在项目目录下新建Frank目录,将Frank的源代码复制进来,然后把所有的lib,src 和 resources 添加到Demo-Frank这个Traget

  3.添加CFNetwork.framework 到Demo-Frank这个Traget

  4.在Demo-Frank这个Traget的"Other Linker Flags"设置项下加入一个flag, "-ObjC"(不要带引号)

  5.修改main.m中代码,如下:

#import <UIKit/UIKit.h>

#ifdef FRANK
#include "FrankServer.h"
static FrankServer *sFrankServer;
#endif

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

#ifdef FRANK
    sFrankServer = [[FrankServer alloc] initWithDefaultBundle];
    [sFrankServer startServer];
#endif
    
    int retVal = UIApplicationMain(argc, argv, nil, @"YouProjectAppDelegate");
    [pool release];
    return retVal;
}

  6.开启accessibility功能。在OSX下,进入System Preferences -> Universal Access,然后选中"Enable access for assistive devices"。在模拟器下,进入Settings -> General -> Accessibility -> Accessibility Inspector 选择"on"。

  7.在 Demo-Frank 这个 Target 下进入 Run Script, 在 shell 后面的输入框中键入 /bin/sh, 在 shell 下面的输入框中输入

echo "Copying build to FrankDeploy directory"
eche ${BUILD_DIR}
ditto "${BUILD_DIR}/Debug-iphonesimulator/YourProject.app"
 "./FrankDeploy/YourProject_Frank.app"

  8.编译运行Demo-Frank,(如果存在通过网络连接获取数据,确保能正常连接,注意防火墙的设定),然后进入你要测试的场景界面。

  9.打开浏览器,输入http://localhost:37265,点击右上角的Refresh按钮,当载入完毕后可以看到所有这个界面的elements信息(每次重启Demo-Frank或者要切换测试场景的时候都需要点击Refresh按钮,去获取当前的elements信息)。

  如上图所示,当前页面有一个UILabel,它的accessibilityLabel被设置为"UserID:",可以在elements tree西面找到该element。然后在页面最上方"View DOM"的Selector中输入"label marked:'UserID:'",然后点击Flash,在Xcode的输出窗口中可以看到相应的输入信息,如果输入一个不存在的Selector将会弹出提示,告知你当前的元素不存在。

在"Accessibility Elements"当中,会显示当前所有设置有AccessibilityLabel属性element,缩放浏览器和模拟器,让他们能在一个桌面上完全呈现,点击某一个element,看看有什么神奇的效果? 你点中的那个element,在界面上会闪动!

开始编写自动化测试代码

1.在项目目录下新建features目录,该目录用于放置所有需要运行自动化测试的内容。features目录下面新建2个目录step_definitions和support。

2.在support目录下新建一个env.rb文件,其内容如下

require 'frank-cucumber'

3.在step_definitions目录下新建lunch_steps.rb,其内容如下

Given /^I launch the app$/ do

  # kill the app if it's already running, just in case this helps 
  # reduce simulator flakiness when relaunching the app. Use a timeout of 5 seconds to 
  # prevent us hanging around for ages waiting for the ping to fail if the app isn't running
  begin
    Timeout::timeout(5) { press_home_on_simulator if frankly_ping }
  rescue Timeout::Error 
  end

  require 'sim_launcher'

  
  app_path = ENV['APP_BUNDLE_PATH'] || app_bundle_path
  simulator_version = ENV['IOS_SIMULATOR_VERSION'] || "5.0"
    
  raise "APP_BUNDLE_PATH was not set. \nPlease set a APP_BUNDLE_PATH ruby constant or environment variable to the path of your compiled Frankified iOS app bundle" if app_path.nil?

  if( ENV['USE_SIM_LAUNCHER_SERVER'] )
    simulator = SimLauncher::Client.for_ipad_app( app_path, simulator_version )
  else
    simulator = SimLauncher::DirectClient.for_ipad_app( app_path, simulator_version )
  end
  
  num_timeouts = 0
  loop do
    begin
      simulator.relaunch
      wait_for_frank_to_come_up
      break # if we make it this far without an exception then we're good to move on

    rescue Timeout::Error
      num_timeouts += 1
      puts "Encountered #{num_timeouts} timeouts while launching the app."
      if num_timeouts > 3
        raise "Encountered #{num_timeouts} timeouts in a row while trying to launch the app." 
      end
    end
  end

  # TODO: do some kind of waiting check to see that your initial app UI is ready
  # e.g. Then "I wait to see the login screen"

end

3.在feature目录下新建demo.feature,其内容如下

Scenario: When I lunch the app
    Then I should see the "UserID:" label

4.在step_definitions目录下新建login.rb,其内容如下

Then /^I should see the "([^"]*)" label$/ do |name|
  check_element_exists("label marked:'#{name}'")
end

5.打开Terminal,进入项目目录,输入cucumber demo.feature,即可进行自动测试,如果有多个feature文件需要进行测试,直接输入cucumber,即可对features目录下的所有feature文件进行测试

  写在最后,在自动化测试的过程中,我们需要熟悉Ruby,在feature文件中实际上我们写的就是一些模拟的用户行为,在rb文件中实际上我们写的是针对于这些行为做的解析和动作。过段时间,针对如何写feature和rb会有更加详细的说明。


你可能感兴趣的:(自动化测试,frank)