如何在ios9中进行segue的单元测试

如何在ios9中进行segue的单元测试,ios,swift,unit-testing,Ios,Swift,Unit Testing,我在互联网上搜索了几天,没有找到确切的例子对于简单类。我已经创建了单元测试。我想在segue和unwind segue上进行单元测试。 我该怎么做? ProfileTableViewController是左侧的控制器。 seedTailViewController是右侧的控制器。 ProfileTableViewController: import UIKit class ProfileTableViewController: UITableViewController { var

我在互联网上搜索了几天,没有找到确切的例子
对于简单类。我已经创建了单元测试。
我想在segue和unwind segue上进行单元测试。

我该怎么做?
ProfileTableViewController
是左侧的控制器。
seedTailViewController
是右侧的控制器。
ProfileTableViewController

import UIKit

class ProfileTableViewController: UITableViewController {

    var profiles = [Profile]();
    var profileNew : Profile?;

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1;
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return profiles.count;
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "ProfileTableViewCell";
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! ProfileTableViewCell
        let profile = profiles[indexPath.row];
        cell.nameLabel.text = profile.name;
        cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true);
        let row = indexPath.row;
        print("Row:\(row)");
        print(profiles[row].name , profiles[row].age);
        performSegueWithIdentifier("segueTest", sender: row);
    }

    // Mark: Actions
    @IBAction func backFromOtherController(segue: UIStoryboardSegue) {
        NSLog("I'm back from other controller!")
        print(profileNew?.name);

        //add the new profile
        if(profileNew != nil){
            profiles += [profileNew!];
            //update the tableview
            tableView.reloadData();

        }

    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
        if(segue.identifier == "segueTest"){
            let svc = segue.destinationViewController as! SeeDetailViewController
            let rowid = sender as! Int;
            svc.NamePassed = profiles[rowid].name;
            svc.AgePassed = profiles[rowid].age;
            svc.DescPassed = profiles[rowid].description;
            svc.SpecPassed = profiles[rowid].specialty;

        }
    }
}
import UIKit

public class SeeDetailViewController: UIViewController {

    // Mark: Properties
    @IBOutlet weak var NameLabel: UILabel!
    @IBOutlet weak var AgeLabel: UILabel!
    @IBOutlet weak var SpecialtyLabel: UILabel!
    @IBOutlet weak var descTextView: UITextView!

    var NamePassed : String!;
    var AgePassed : Int!;
    var SpecPassed : String!;
    var DescPassed : String!;

    override public func viewDidLoad() {
        super.viewDidLoad()
        NameLabel.text = NamePassed;
        let myString = String(AgePassed);
        AgeLabel.text = myString;
        SpecialtyLabel.text = SpecPassed;
        descTextView.text = DescPassed;
    }

    override public func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // Mark: Actions
    @IBOutlet weak var HitCall: UIButton!

    @IBAction func alertControllerAction(sender: AnyObject) {
        if(sender.tag == 0 ){
            print("Touch down!");
            let alertController = UIAlertController(title: "Hello!", message: "My name is \(NamePassed)", preferredStyle: .Alert)

            let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action:UIAlertAction!) in
                print("you have pressed the Cancel button");
            }
            alertController.addAction(cancelAction)

            let OKAction = UIAlertAction(title: "OK", style: .Default) { (action:UIAlertAction!) in
                print("you have pressed OK button");
            }
            alertController.addAction(OKAction)

            self.presentViewController(alertController, animated: true, completion:nil)
        }
    }
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
    }
    */

}
seedTailViewController

import UIKit

class ProfileTableViewController: UITableViewController {

    var profiles = [Profile]();
    var profileNew : Profile?;

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1;
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return profiles.count;
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "ProfileTableViewCell";
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! ProfileTableViewCell
        let profile = profiles[indexPath.row];
        cell.nameLabel.text = profile.name;
        cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true);
        let row = indexPath.row;
        print("Row:\(row)");
        print(profiles[row].name , profiles[row].age);
        performSegueWithIdentifier("segueTest", sender: row);
    }

    // Mark: Actions
    @IBAction func backFromOtherController(segue: UIStoryboardSegue) {
        NSLog("I'm back from other controller!")
        print(profileNew?.name);

        //add the new profile
        if(profileNew != nil){
            profiles += [profileNew!];
            //update the tableview
            tableView.reloadData();

        }

    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
        if(segue.identifier == "segueTest"){
            let svc = segue.destinationViewController as! SeeDetailViewController
            let rowid = sender as! Int;
            svc.NamePassed = profiles[rowid].name;
            svc.AgePassed = profiles[rowid].age;
            svc.DescPassed = profiles[rowid].description;
            svc.SpecPassed = profiles[rowid].specialty;

        }
    }
}
import UIKit

public class SeeDetailViewController: UIViewController {

    // Mark: Properties
    @IBOutlet weak var NameLabel: UILabel!
    @IBOutlet weak var AgeLabel: UILabel!
    @IBOutlet weak var SpecialtyLabel: UILabel!
    @IBOutlet weak var descTextView: UITextView!

    var NamePassed : String!;
    var AgePassed : Int!;
    var SpecPassed : String!;
    var DescPassed : String!;

    override public func viewDidLoad() {
        super.viewDidLoad()
        NameLabel.text = NamePassed;
        let myString = String(AgePassed);
        AgeLabel.text = myString;
        SpecialtyLabel.text = SpecPassed;
        descTextView.text = DescPassed;
    }

    override public func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // Mark: Actions
    @IBOutlet weak var HitCall: UIButton!

    @IBAction func alertControllerAction(sender: AnyObject) {
        if(sender.tag == 0 ){
            print("Touch down!");
            let alertController = UIAlertController(title: "Hello!", message: "My name is \(NamePassed)", preferredStyle: .Alert)

            let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action:UIAlertAction!) in
                print("you have pressed the Cancel button");
            }
            alertController.addAction(cancelAction)

            let OKAction = UIAlertAction(title: "OK", style: .Default) { (action:UIAlertAction!) in
                print("you have pressed OK button");
            }
            alertController.addAction(OKAction)

            self.presentViewController(alertController, animated: true, completion:nil)
        }
    }
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
    }
    */

}

对视图控制器序列进行单元测试的一种简单方法(尽管它打破了一些抽象)如下所示:

  • 创建一个变量,例如,
    calledSegue
    ,它最初有一个nil值
  • 覆盖目标视图控制器的
    performsguewithidentifier:
    功能,以便将
    calledSegue
    设置为被调用的segue标识符。确保在重写的函数中也调用
    super.performsguewithidentifier:
    ,以保留原始函数的行为
  • 创建一个单元测试,检查在测试条件下
    calledSegue
    是否设置为预期的segue标识符
  • 如中所述,您可以使用未记录的API来获取segues。然后,您可以这样编写测试:

    class MyViewControllerTests: XCTestCase {
    
        var SUT: MyViewController!
    
        override func setUp() {
            super.setUp()
    
            SUT = UIStoryboard(name: "MyStoryboard", bundle: Bundle(for: MyViewController.self)).instantiateViewController(withIdentifier:String(describing: MyViewController.self)) as! MyViewController
            let _ = SUT.view
        }
    
        override func tearDown() {
            SUT = nil
            super.tearDown()
        }
    
        // Mark: - Test Methods
    
        func testSegues() {
            let identifiers = segues(ofViewController: SUT)
            XCTAssertEqual(identifiers.count, 2, "Segue count should equal two.")
            XCTAssertTrue(identifiers.contains("ExitSegueIdentifier"), "Segue ExitSegueIdentifier should exist.")
            XCTAssertTrue(identifiers.contains("ShowDetailViewController"), "Segue ShowDetailViewController should exist.")
        }
    
        // Mark: - Helper Methods
    
        func segues(ofViewController viewController: UIViewController) -> [String] {
            let identifiers = (viewController.value(forKey: "storyboardSegueTemplates") as? [AnyObject])?.flatMap({ $0.value(forKey: "identifier") as? String }) ?? []
            return identifiers
        }
    
    }
    

    让我完成UITest,我将再次发布我的测试。谢谢。请你详细说明一下,或者给我一份医生。我通常在单元测试主题上找到objective-C内容。