一. iOS单元测试,UI测试基本介绍
二. KIF简介
三. KIF集成
四. 测试用例编写
五. jenkins集成步骤
六. 总结
一 iOS单元测试,UI测试基本介绍
1.1 简单介绍
iOS有两个层次的测试:单元测试,UI测试。
单元测试:XCTest,XCTest最后生成的是一个bundle。bundle是不能直接执行的,必须依赖于一个宿主进程。XCTest主要基础功能:异步测试,性能测试,代码覆盖率等。
UI测试:UI Testing,UI测试是模拟用户操作,进而从业务处层面测试,iOS UI测试还有一个核心功能是UI Recording。选中一个UI测试用例,然后点击图中的小红点既可以开始UI Recoding,录制完成之后,会自动生成一段测试代码。
1.2 项目中如何集成
如果是一个新项目,在创建项目的时候,直接勾选 include Unit Tests,和include UI Tests 即可,如下图:
iOS 新项目如何加入单元测试和UI测试.png
1.2 已有项目中如何集成
如果我们有一个已有项目,可能前期没有加入测试框架,那么后期我们如何引入呢,步骤如下图:
步骤一 :点击项目工程,在配置文件右下角点击+号会弹出一个选择框
步骤二 :下滑到test一栏,这里就找到了单元测试和UI测试,这里我们选择iOS UnitTesing Bundle
步骤三 :填写一些基本信息,
步骤三
步骤四 :添加成功的页面,Testable SwiftTests目录就是就是我们刚生成的,今后的测试用例也都是在这个目录下面写。
步骤四
总结:这里只是简单的介绍iOS测试方面的一些东西,我们今天的主要目的是讲一个第三方的UI测试框架,以及如何结合jenkins做自动化测试,所以这里就不详细介绍了,下面开始介绍我们的主题。
二. KIF简介
2.1 简要说明
KIF代表Keep It Functional,是一款iOS集成测试框架。 通过利用操作系统为具有视觉障碍的用户提供的辅助功能属性,可以轻松实现iOS应用程序的自动化。
KIF使用标准的XCTest测试目标来构建和执行测试。 测试在主线程中同步进行(运行运行循环以强制时间流逝),从而允许更复杂的逻辑和组合。 这也使得KIF能够利用Xcode Test Navigator,命令行构建工具和Bot测试报告。
KIF使用未公开的Apple API。 大多数iOS测试框架都是如此,并且对于测试目的而言是安全的,但重要的是KIF不会将其转换为生产代码,因为它会让您的应用程序提交被Apple拒绝。 按照下面的说明确保KIF为您的项目配置正确。
KIF是基于XCTest的一个第三方UI测试框架,XCTest是iOS的单元测试框架,所以项目中加入XCTest框架可以做单元测试,又通过引入KIF框架做UI集成测试。
2.2 功能特性
1 最小化间接性
所有的KIF测试都是用Objective-C编写的。 这可以最大程度地集成代码,同时最大限度地减少必须构建的图层数量。
2 简单的配置
KIF直接集成到您的Xcode项目中,因此无需运行其他Web服务器或安装任何其他软件包。
3 宽操作系统和Xcode覆盖
KIF的测试套件正在针对iOS 8+和Xcode 7+运行。 较低的版本可能仍然有效,但你的里程可能会有所不同。 我们尽最大努力保留向后兼容性。
4 像用户一样测试
KIF试图模仿实际的用户输入。 尽可能使用触摸事件来完成自动化。
5 与Xcode测试工具自动集成
您可以使用测试导航器轻松运行单个KIF测试,或者使用机器人启动每晚验收测试。
三. KIF集成
我们通过cocopod来进行引入
步骤一
项目中要先引入XCTest,引入步骤和方法,可以参考本文上面(1.2 已有项目中如何集成 )章节
步骤二
打开工程里的Podfile文件加入以下代码:
target 'MyApp' do
pod 'Alamofire'
pod 'SwiftProgressHUD'
pod 'WechatOpenSDK'
pod 'Bugly'
end
target 'MyAppTests' do
pod 'KIF'
end
这里要注意target是项目的Tests,不要加错位置了,当初我就加错了加到target "MyApp",然后在写测试用例是引入KIF.h,总是报错,可能当时没太注意这个细节,结果掉坑里了。编辑完成,pod install 一下。
步骤三
1: 项目名Tests对象 (项目名+Tests)---> Build Phase ---> Target Dependencies ---> "+" --->"项目的Tests文件"(去百度一下这个 tests 文件 和UItests 文件有什么区别)
2: 项目名Tests对象 ---> Build Settings ---> Linking(直接搜)---> Bundle Loader 填写"$(BUILT_PRODUCTS_DIR)/项目名称.app/项目名称"
3: 项目名Tests对象 ---> Build Settings ---> Wrapper Extension (直接搜)设置成 "xctest"
4: 点击你 RUN 按钮前面的前面的项目target ---> Edit Scheme... ---> Test 看看里面有没有你要测试的项目,没有就添加
步骤四
在Tests目录下创建一个桥接文件(创建桥接文件,可以在当前目录下新建一个oc文件,xcode中途会提示是否创建桥接文件,桥接文件创建完成后,再把oc文件删除就行了),KIF是OC写的,用swift写测试用例就要创建一个桥接文件,oc的话就不用了。
总结:自此,KIF我们就已经集成完毕了,下面就开始我们测试用例的编写了。
四. 测试用例编写
我们写了一个登陆流程的示例:新建一个LoginTest.swift文件有几个注意点:
1 要导入KIF头文件 import KIF
2 底层没有提供tester方法,所以要加一个扩展
3 类要继承 KIFTestCase类
4 tester().usingLabel("login_phone"),使用usingLabel获取控件,前提是项目中这个控件的要设置accessibilityLabel 属性
LoginTests.swift
import XCTest
import KIF
extension XCTestCase {
func tester(_ file : String = #file, _ line : Int = #line) -> KIFUIViewTestActor {
return KIFUIViewTestActor(inFile: file, atLine: line, delegate: self)
}
func system(_ file : String = #file, _ line : Int = #line) -> KIFSystemTestActor {
return KIFSystemTestActor(inFile: file, atLine: line, delegate: self)
}
}
class LoginTests: KIFTestCase {
func testLogin(){
noInputLogin()
noValidateLogin()
validateLogin()
agreeValidateLogin()
}
func testAdd() {
let a = 3
let b = 4
XCTAssert(a+b == 7, "计算正确")
}
func testnoValidateLogin(){
let userNameInput = tester().usingLabel("login_phone")
userNameInput?.enterText("15856885688")
let loginBtn = tester().usingLabel("登录")
loginBtn?.tap()
tester().wait(forTimeInterval: 2)
}
func noInputLogin(){
let loginBtn = tester().usingLabel("登录")
loginBtn?.tap()
tester().wait(forTimeInterval: 2)
}
func noValidateLogin(){
let userNameInput = tester().usingLabel("login_phone")
userNameInput?.enterText("15856885688")
let loginBtn = tester().usingLabel("登录")
loginBtn?.tap()
tester().wait(forTimeInterval: 2)
}
func validateLogin(){
let invalicaodeInput = tester().usingLabel("login_input_invlicode")
invalicaodeInput?.enterText("123456")
let valicodeBtn = tester().usingLabel("获取验证码")
valicodeBtn?.tap()
let loginBtn = tester().usingLabel("登录")
loginBtn?.tap()
tester().wait(forTimeInterval: 2)
}
func agreeValidateLogin(){
let login_agree = tester().usingLabel("login_agree")
login_agree?.tap()
let loginBtn = tester().usingLabel("登录")
loginBtn?.tap()
let firstPage = tester().usingLabel("首页").waitForView()
if (firstPage != nil) {
loginOut()
} else {
XCTAssert(false, "未找到页面")
}
}
func loginOut(){
let meBtn = tester().usingLabel("我")
meBtn?.tap()
let setUpBtn = tester().usingLabel("设置")
setUpBtn?.tap()
let outBtn = tester().usingLabel("退出登录")
outBtn?.tap()
tester().wait(forTimeInterval: 5)
}
}
所有的测试方法要以test头,不以test开头的方法,测试是不会执行的,但可以作为内置方法,其他的测试方法可以调用。这里只做一个示例具体使用请参考官方文档:https://github.com/kif-framework/KIF,官方demo它提供了如下一些操作示例:
到此KIF集成,使用流程,我们基本介绍完了。下面我们看下如何结合jenkins做自动化测试
五. jenkins集成步骤
步骤一
首先我们要把已经完成的测试用例的项目上传到一个git仓库里。
步骤二
1 启动jenkins,新建item,构建一个自由风格的项目,输入名称点击确定,接下来就是job配置。
2 主要配置后五项,源码管理,构建触发器,构建环境,构建,构建后操作。
项目配置
3 源码管理
源码管理
这里就是填写你的仓库路径,授权账户,分支。
4 构建触发器
构建触发器
这里根据不同的需求,可以自定义触发脚本运行时机。这里设置构建触发器*/2 * * * *,每2分钟检查一次源码变化。
5 构建环境
此项可不用配置
输入脚本:
#!/bin/bash -l
#新建目录用于保存报告
mkdir test-reports
#pod可能失败的全局参数设置
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
pod install
#xcodebuild test -workspace XXX.xcworkspace -scheme XXXTests -destination 'platform=iOS Simulator,name=iPhone 6s'跑[<u style="margin: 0px auto; padding: 0px; font-family: "microsoft yahei";">**测试用例**</u>](javascript:;)
#-enableCodeCoverage YES 收集[<u style="margin: 0px auto; padding: 0px; font-family: "microsoft yahei";">**测试覆盖率**</u>](javascript:;)
#ocunit2junit 输出报告转换为jenkins可读的[<u style="margin: 0px auto; padding: 0px; font-family: "microsoft yahei";">**junit**</u>](javascript:;)报告
xcodebuild test -workspace XXX.xcworkspace -scheme XXXTests -destination 'platform=iOS Simulator,name=iPhone 6s' -configuration Debug -enableCodeCoverage YES 2>&1 | ocunit2junit
#slather coverage转换覆盖率报告为html文件,jenkins可读
#--input-format profdata xcode生成的为profdata格式的文件,转换为html以便jenkins显示
#--ignore 排除筛选需要计算的文件,多个格式写多个ignore表达式
slather coverage --html --input-format profdata --binary-basename XXXApp --scheme XXXTests --workspace XXX.xcworkspace --configuration Debug --ignore **View** --ignore **AppText** --output-directory reports XXX.xcodeproj
这里用到两个工具, ocunit2junit 以及slather.
打开mac终端安装
sudo gem install ocunit2junit
sudo gem install slather
7 构建后操作
读取显示junit和覆盖率html报告
这里用到两个jenkins插件,jenkins->系统管理-> 管理插件,找到JUnit Plugin和HTML Publisher plugin,安装重启jenkins,如果没安装这两个插件的话,构建后操作步骤是没有这两个选项的
选择Publish Junit test result report,配置xml文件路径为第三步配置的test-reports/*.xml。
junit结果报告再增加一个构建后操作,选择Publish HTML reports, 配置html路劲为第三步配置的reports,Index文件为index.html,可以设置标题Reports title为Coverage Report。
HTML覆盖率报告配置保存返回,点击立即构建,等待构建完成,返回job主页,可以看到junit测试结果报告和覆盖率的图表了。
UI自动化构建结果
到此整个jenkins集成完毕了,以后就可以愉快的跑UI测试了
六. 总结
项目中对于单元测试,UI测试我们可以单独拉取一个分支,专门作为测试分支,每次代码提交前,先合并到这个测试分支,然后jenkins就会开始跑你所有的测试用例,如果我们写了很多测试用例,有很多个测试用例文件,我们要指定跑哪几个怎么办,看下图:
image.png
EditScheme->Test
把你不想跑的测试用例直接勾掉就行了,然后保存推送到git仓库就行了,这里还有一个注意的,上文讲的覆盖率报告的生成,这里有个Code Coverage选项要勾上才行。
网友评论