1, 애플의 공식 테스트 프레임 워크 XCTest의 장점과 단점
장점 :와 엑스 코드의 깊이의 통합, 전용 테스트 탐색 모음.
단점 :
1 ) 제한된 공식 테스트의 때문에 API , 따라서 기능이 매우 풍부하지 않습니다.
2 ) 작성 및 가독성이 매우 좋지 않다. 다양한 시험 방법의 조각이기 때문에 너무 많은 테스트의 경우, 긴 테스트 파일의 특정 테스트를 발견하고 철저하게이 테스트 할 수있는 아주 쉬운 일이 아니다 이해하고 싶다.
3 ) 모든 시험은 종종 이해하거나 변환 비용이 많이 걸립니다, 주장에 의해 수행, 매우 자주 프로젝트의 배달하거나 새로운 개발자가 참여하는 방법에 대한, 특히 명확하지 의미 주장했다. 또한, 각 테스트의 설명이 주장 이후에 기록 된 코드에 포함, 찾기 어렵다.
4 ) 사용 XCTest의 시험 또 다른 문제는 어려운 조롱하거나 스텁
왜 빠른 + 민첩을 사용할 수 있습니까?
주로 애플의 공식 시험 방법 및 주장 프레임 워크, 명확한 가독성 나쁘지 않다에, 우리는 거의 시간 전송 프로젝트를 많이 지출 할 필요가 없습니다 때문에, 노사정 프레임 워크를 테스트하는 것이 좋습니다
주류 삼자 테스트 프레임 워크입니다 :
빠른 : 빠른 + 민첩 , 의 Sleipnir
이 프로젝트는 언어의 신속한 사용, 그래서의 주요 사용하기 때문에 빠른 + 민첩한 단위 테스트 및 주장에 대한이.
프로젝트가 OC의 경우, 우리는 추천 키위를 현재 최대 규모의 시작 노사정 프레임 워크입니다.
2, 빠른 + 민첩 소개
빠른 a는 내장되어 XCTest을 위해에 스위프트 와 오브젝티브 C의 테스트 프레임 워크 설계 . 시험 사용 스위프트를 작성하는 응용 프로그램 매우 친절 에 대한 스위프트 , 사용자 빠른 최선의 선택을.
그것은 통해 DSL 과 매우 유사 쓰기 RSpec에의 테스트 케이스.
민첩한 같은 빠른 , 주장으로 일치 작성하기위한 모드를 일치 제공 파트너.
3, 빠른 + 민첩한 사용
1) 구성 빠른 + 민첩
(1) cocopod 빠른 + 민첩, 포드 설명 파일을 설치 다음 사용
platform :ios, '9.0'
use_frameworks!
def testing_pods
pod 'Quick', '~>1.0.0'
pod 'Nimble', '~>5.0.0'
end
target 'testTests' do
testing_pods
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '3.2'
end
end
end
(2) 단자 창에서 수행 설치
(3) 사용하기 전에, 프로젝트 빌드 settting에 필요한 엑스 코드는 모듈로 설정 정의합니다 예
(4) 빌드 단계에서 -> 라이브러리와 링크 진은 프레임에 도입
2) 빠른 + 민첩를 사용
(1) 상기 프레임 검사 파일에
import Quick
import Nimble
(2) 대상 항목에 테스트 가져 오기 파일에서 테스트 할
//这一行基本上就是标示出我们正在测试的项目目标,然后允许我们从那里 import classes
@testable import test
(3)에 테스트 파일의 유형 상속 용 QuickSpec을 , 우리의 클래스 용 QuickSpec의 서브 클래스인지 확인해야합니다, 그것은 또한 XCTestCase 서브 클래스를했다.
하나의 사양 방법은 모든 시험이 방법에있다,있다
import Quick
import Nimble
@testable import test
class BananaTests: QuickSpec {
override func spec(){
//所有测试放在这里
}
}
(4) 시험 기록 형식
테스트를위한 돌고래 클래스 만들기
public struct Click{
public var isLoud = true
public var hasHighFrequency = true
public func count()->Int{
return 1
}
}
class Dolphin {
public var isFriendly = true
public var isSmart = true
public var isHappy = false
public init(){
}
public init(_ happy : Bool){
isHappy = happy
}
public func click()->Click{
return Click()
}
public func eat(_ food : AnyObject){
isHappy = true
}
}
시험 형식의 형식, 즉 세 축 소정 -시 - 다음 / 정렬 - 행동 - 어설
애플의 공식 XCTest를 사용하는 첫 번째
func testA_Dolphin_its_click_whenTheDolphinIsNearSomethingInteresting(){
//given / arrange
let dolphin : Dolphin = Dolphin()
//when / act
let click = dolphin.click()
//then / assert
XCTAssertEqual(click.count(), 3)
}
func testA_Dolphin_its_click_whenTheDolphinIsNotNearAnythingInteresting(){
//given / arrange
let dolphin : Dolphin = Dolphin()
//when / act
let click = dolphin.click()
//then / assert
XCTAssertEqual(click.count(), 1)
}
이어서 민첩한 프레임 주장을 대체
func testA_Dolphin_its_click_whenTheDolphinIsNearSomethingInteresting(){
//given / arrange
let dolphin : Dolphin = Dolphin()
//when / act
let click = dolphin.click()
//then / assert
// XCTAssertEqual(click.count(), 3)
expect(click.count()).to(equal(3))
}
func testA_Dolphin_its_click_whenTheDolphinIsNotNearAnythingInteresting(){
//given / arrange
let dolphin : Dolphin = Dolphin()
//when / act
let click = dolphin.click()
//then / assert
// XCTAssertEqual(click.count(), 1)
expect(click.count()).to(equal(1))
}
마지막으로, 공식 대조적으로 빠른 + 민첩 사용
import Quick
import Nimble
@testable import test
class DolphinQuickTests: QuickSpec {
override func spec(){
//所有测试放在这里
// describe用于描述类和方法
describe("a dolphin", closure: {
var dolphin : Dolphin!
// beforeEach/afterEach相当于setUp/tearDown,beforeSuite/afterSuite相当于全局setUp/tearDown
beforeEach {
dolphin = Dolphin()
}
describe("its click", closure: {
var click : Click!
beforeEach {
click = dolphin.click()
}
// context用于指定条件或状态
context("when the dolphin is not near anything interesting", closure: {
// it用于描述测试的方法名
it("it only emited once", closure: {
expect(click.count()).to(equal(1))
})
})
context("when the dolphin is near something interesting", closure: {
it("it emited three times", closure: {
expect(click.count()).to(equal(3))
})
})
})
})
}
}
대비 결론 :
1 없음) 더 이상 공식 빠른는 특히 긴에서 메소드 이름과 동일한 프레임에
2 ) 민첩한 보다 간결이 , 자연 언어 구문에 가까운 ,
3 ) 빠른 우리가 설명이 더 많은 테스트를 작성할 수 있습니다 , 그리고 , 우리의 코드를 단순화하기 위해 , 특히 arrange
코드의 위상을 .
4, 빠른 키워드 설명
키워드 | 용도 |
설명 | 클래스에 기재된 방법과 |
문맥 | 조건이나 상태를 지정합니다 |
그것 | 이름은 시험 방법을 설명하는 데 사용 |
beforeEach / afterEach | 등가 SETUP /의 tearDown |
beforeSuite / afterSuite | 글로벌 SETUP / 해체 상당 |
在describe 、context、it前加“x” | 表示可以屏蔽此方法的测试 |
在describe 、context、it前加“f” | 表示可以只测试这些带f的测试 |
5、Nimble关键字说明
Nimble一般使用 expect(...).to
和 expect(...).notTo
的写法
1)支持异步测试
dispatch_async(dispatch_get_main_queue()) {
ocean.add("dolphins")
ocean.add("whales")
}
expect(ocean).toEventually(contain("dolphins"), timeout: 3)
2)使用waitUntil来进行等待
waitUntil { done in
// do some stuff that takes a while...
NSThread.sleepForTimeInterval(0.5)
done()
}
3)列举Nimble中的匹配函数
用途 | 函数 |
等值判断 | 使用equal函数 expect(actual).to(equal(expected)) expect(actual) == expected expect(actual) != expected |
是否是同一个对象 |
使用beIdenticalTo函数 expect(actual).to(beIdenticalTo(expected)) expect(actual) === expected expect(actual) !== expected |
比较 | expect(actual).to(beLessThan(expected)) expect(actual) < expected
expect(actual).to(beLessThanOrEqualTo(expected)) expect(actual) <= expected
expect(actual).to(beGreaterThan(expected)) expect(actual) > expected
expect(actual).to(beGreaterThanOrEqualTo(expected)) expect(actual) >= expected |
比较浮点数 | expect(10.01).to(beCloseTo(10, within: 0.1)) |
类型检查 |
expect(instance).to(beAnInstanceOf(aClass)) expect(instance).to(beAKindOf(aClass)) |
是否为真 |
// Passes if actual is not nil, true, or an object with a boolean value of true: expect(actual).to(beTruthy())
// Passes if actual is only true (not nil or an object conforming to BooleanType true): expect(actual).to(beTrue())
// Passes if actual is nil, false, or an object with a boolean value of false: expect(actual).to(beFalsy())
// Passes if actual is only false (not nil or an object conforming to BooleanType false): expect(actual).to(beFalse())
// Passes if actual is nil: expect(actual).to(beNil()) |
是否有异常 |
// Passes if actual, when evaluated, raises an exception: expect(actual).to(raiseException())
// Passes if actual raises an exception with the given name: expect(actual).to(raiseException(named: name))
// Passes if actual raises an exception with the given name and reason: expect(actual).to(raiseException(named: name, reason: reason))
// Passes if actual raises an exception and it passes expectations in the block // (in this case, if name begins with 'a r') expect { exception.raise() }.to(raiseException { (exception: NSException) in expect(exception.name).to(beginWith("a r")) }) |
集合关系 |
// Passes if all of the expected values are members of actual: expect(actual).to(contain(expected...)) expect(["whale", "dolphin", "starfish"]).to(contain("dolphin", "starfish"))
// Passes if actual is an empty collection (it contains no elements): expect(actual).to(beEmpty())
|
字符串 |
// Passes if actual contains substring expected: expect(actual).to(contain(expected))
// Passes if actual begins with substring: expect(actual).to(beginWith(expected))
// Passes if actual ends with substring: expect(actual).to(endWith(expected))
// Passes if actual is an empty string, "": expect(actual).to(beEmpty())
// Passes if actual matches the regular expression defined in expected: expect(actual).to(match(expected)) |
检查集合中的所有元素是否符合条件 |
// with a custom function: expect([1,2,3,4]).to(allPass({$0 < 5}))
// with another matcher: expect([1,2,3,4]).to(allPass(beLessThan(5))) |
检查集合个数 |
expect(actual).to(haveCount(expected)) |
匹配任意一种检查 |
// passes if actual is either less than 10 or greater than 20 expect(actual).to(satisfyAnyOf(beLessThan(10), beGreaterThan(20)))
// can include any number of matchers -- the following will pass expect(6).to(satisfyAnyOf(equal(2), equal(3), equal(4), equal(5), equal(6), equal(7)))
// in Swift you also have the option to use the || operator to achieve a similar function expect(82).to(beLessThan(50) || beGreaterThan(80)) |
参考链接: