빠른 민첩 +를 사용하여 신속한 테스트 유닛 (IV) 테스트 워크 성분

1, 애플의 공식 테스트 프레임 워크 XCTest의 장점과 단점

장점 :와  엑스 코드의  깊이의 통합, 전용 테스트  탐색 모음.

단점 :

1 ) 제한된 공식 테스트의 때문에 API , 따라서 기능이 매우 풍부하지 않습니다.

2 ) 작성 및 가독성이 매우 좋지 않다. 다양한 시험 방법의 조각이기 때문에 너무 많은 테스트의 경우, 긴 테스트 파일의 특정 테스트를 발견하고 철저하게이 테스트 할 수있는 아주 쉬운 일이 아니다 이해하고 싶다.

3 ) 모든 시험은 종종 이해하거나 변환 비용이 많이 걸립니다, 주장에 의해 수행, 매우 자주 프로젝트의 배달하거나 새로운 개발자가 참여하는 방법에 대한, 특히 명확하지 의미 주장했다. 또한, 각 테스트의 설명이 주장 이후에 기록 된 코드에 포함, 찾기 어렵다.

4 ) 사용 XCTest의 시험 또 다른 문제는 어려운 조롱하거나 스텁

 

왜 빠른 + 민첩을 사용할 수 있습니까?

주로 애플의 공식 시험 방법 및 주장 프레임 워크, 명확한 가독성 나쁘지 않다에, 우리는 거의 시간 전송 프로젝트를 많이 지출 할 필요가 없습니다 때문에, 노사정 프레임 워크를 테스트하는 것이 좋습니다

주류 삼자 테스트 프레임 워크입니다 :

C의中은, 키위  , 모양 , 잘립니다

빠른 : 빠른 + 민첩 , 의 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))

参考链接:

使用swift给objc项目做单元测试

【CodeTest】TDD,BDD及初步使用Quick

iOS测试与集成

Swift 进阶开发指南:如何使用 Quick、Nimble 执行测试驱动开发(TDD)

추천

출처blog.csdn.net/lin1109221208/article/details/93048812