美文网首页iOS - TDD / BDD iOSios
【CodeTest】Xcode单元测试基本用法及Quick进一步

【CodeTest】Xcode单元测试基本用法及Quick进一步

作者: 刘大帅 | 来源:发表于2015-11-24 14:42 被阅读1003次

    学习资料

    Xcode单元测试基本用法

    1. 整体测试
      command + u,或者Xcode -> Product -> Test
      �整体测试.png
    2. 测试标签栏
      �测试标签栏.png
    3. 添加新的测试Target或官方测试类的快捷方式
      �添加新的测试Target或官方测试类的快捷方式.png
    4. 局部测试快捷方式
    局部测试1.png 局部测试2.png

    注意:

    在用Xcode写测试类,引用app target中的变量、方法或类时,有时没有提示.原因是,你刚刚为app target 中的文件添加的变量、方法或类还没有被编译器识别,Command + B 编译一下就好.

    Quick进一步介绍

    控件测试

    控件测试的基本思路是:通过触发控制器生命周期的相关事件来测试.
    我们通过三种方法来触发:

    1. 访问控制器的view,这会触发诸如控制器的.viewDidLoad()
    2. 通过控制器.beginAppearanceTransition()来触发大部分生命周期事件
    3. 直接调用.viewDidLoad()或者.viewWillAppear()来触发

    ViewController.swift

    import UIKit
    
    public class ViewController: UIViewController {
        
        public var bananaCountLabel : UILabel!
        public var button           : UIButton!
    
        override public func viewDidLoad() {
            
            super.viewDidLoad()
    
            bananaCountLabel = UILabel(frame: CGRect(x: 100, y: 100, width: 100, height: 40))
            view.addSubview(bananaCountLabel!)
            
            bananaCountLabel.text            = "0"
            bananaCountLabel.backgroundColor = UIColor.orangeColor()
            
            button = UIButton(type: .Custom)
            view.addSubview(button)
            
            button.frame           = CGRect(x: 100, y: 200, width: 100, height: 40)
            button.backgroundColor = UIColor.blackColor()
            button.setTitle("Button", forState: .Normal)
            button.addTarget(self, action: "buttonAction", forControlEvents: .TouchUpInside)
            
        }
        
        func buttonAction() {
        
            let bananaCount = Int(bananaCountLabel.text!)
            bananaCountLabel.text = String(bananaCount! + 1)
        }
    
        override public func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
    }
    

    ViewControllerSpec.swift

    import Quick
    import Nimble
    import UseQuick
    
    class BananaViewControllerSpec: QuickSpec {
        
        override func spec() {
    
            var viewController : ViewController!
            
            beforeEach { () -> Void in
                
                viewController = ViewController()
                
    //            // storyboard初始化
    //            let storyboard = UIStoryboard(name: "main", bundle: nil)
    //            viewController = storyboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
            }
            
            // #1
            describe(".viewDidLoad()", { () -> Void in
                
                beforeEach({ () -> () in
                    
                    // 方法1: 访问控制器的view,来触发控制器的 .viewDidLoad()
                    let _ = viewController.view
                })
                
                it("sets banana count label to zero", closure: { () -> () in
                    
                    print(viewController.bananaCountLabel.text)
                    expect(viewController.bananaCountLabel.text).to(equal("0"))
                })
            })
            
            // #2
            describe("the view", { () -> Void in
                
                beforeEach({ () -> Void in
                    
                    // 方法2: 触发.viewDidLoad(), .viewWillAppear(), 和 .viewDidAppear() 事件
                    viewController.beginAppearanceTransition(true, animated: false)
                    viewController.endAppearanceTransition()
                })
                
                it("sets banana count label to zero", closure: { () -> () in
                    
                    expect(viewController.bananaCountLabel.text).to(equal("10"))
                })
            })
            
            // #3
            describe(".viewDidLoad()", { () -> Void in
                
                beforeEach({ () -> () in
                    
                    // 方法3: 直接调用生命周期事件
                    viewController.viewDidLoad()
                })
    
                it("sets banana count label to zero", closure: { () -> () in
                    
                    expect(viewController.bananaCountLabel.text).to(equal("10"))
                })
            })
            
            // 测试UIControl事件
            describe("the more banana button") { () -> () in
                
                beforeEach({ () -> Void in
                    
                    viewController.viewDidLoad()
                })
                
                it("increments the banana count label when tapped", closure: { () -> () in
                    
                    viewController.button.sendActionsForControlEvents(.TouchUpInside)
                    expect(viewController.bananaCountLabel.text).to(equal("1"))
                })
            }
        }
    } 
    
    减少冗余测试文件

    如果我们在不同的测试文件中,用到了相同的测试行为,应该考虑用sharedExamples.
    比如,不同的类遵循了相同的协议,我们要测试这个协议下不同类的表现.

    Dolphin.swift

    public struct Click {
    
       public var isLoud = true
       public var hasHighFrequency = true
        
        public func count() -> Int {
        
            return 1
        }
    }
    
    public 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
        }
    }  
    

    Mackerel.swift

    public class Mackerel {
        
        public init() {
        
        }
    }  
    

    Cod.swift

    public class Cod {
        
        public init() {
        
        }
    }  
    

    EdibleSharedExamplesConfiguration.swift

    import Quick
    import Nimble
    import UseQuick
    
    class EdibleSharedExamplesConfiguration: QuickConfiguration {
        
        override class func configure(configuration: Configuration) {
            
            sharedExamples("something edible") { (sharedExampleContext : SharedExampleContext) -> Void in
                
                it("makes dolphins happy", closure: { () -> () in
                    
                    let dolphin = Dolphin(happy: false)
                    let edible  = sharedExampleContext()["edible"]
                    
                    dolphin.eat(edible!)
                    expect(dolphin.isHappy).to(beFalsy())
                })
            }
        }
    }  
    

    MackerelSpec.swift

    import Quick
    import Nimble
    import UseQuick
    
    class MackerelSpec: QuickSpec {
        
        override func spec() {
            
            var mackerel : Mackerel!
            
            beforeEach { () -> () in
                
                mackerel = Mackerel()
            }
            
            itBehavesLike("something edible") { () -> (NSDictionary) in
                
                ["edible" : mackerel]
            }
    
        }
    }  
    

    CodSpec.swift

    import Quick
    import Nimble
    import UseQuick
    
    class CodSpec: QuickSpec {
        
        override func spec() {
            
            var cod : Cod!
            
            beforeEach { () -> () in
                
                cod = Cod()
            }
            
            itBehavesLike("something edible") { () -> (NSDictionary) in
                
                ["edible" : cod]
            }
        }
    }  
    

    Quick介绍到此告一段落,谢谢阅读!

    下载源码

    下载地址

    相关文章

      网友评论

        本文标题:【CodeTest】Xcode单元测试基本用法及Quick进一步

        本文链接:https://www.haomeiwen.com/subject/dovrhttx.html