Swift中的功能测试.模拟应用程序流程

Mat*_*oal 8 testing functional-testing swift

我正在尝试在Swift中执行一些非常简单的功能/功能测试,但我有一些疑问,我需要解决才能创建有用的测试.

我想验证由另一个Controller提供的Controller是否存在于应用程序导航层次结构中(如果Controller已经被呈现为NavigationController,如Modal或其他什么,则无关紧要).

如果我以编程方式实例化并显示控制器,直接进入测试功能,当我检查On Top控制器时,我总是得到Storyboard根控制器而不是我刚刚实例化的控制器,好像我手动创建的控制器永远不会添加到应用程序层次结构中.

这里是伪代码的一个例子:

func testController(){ 

    // Instantiate a controller 
    let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle(forClass: self.dynamicType))
    let controller1 = storyBoard.instantiateViewControllerWithIdentifier("Controller1") as? ControllerOneViewController
    controller1.loadView()

    // Call a function that instantiates another controller 
    controller1.pushAnotherController()

    // Test that the current shown controller is what we expect... 
    let rootController = UIApplication.sharedApplication().keyWindow?.rootViewController
    XCTAssert(rootController.self == TheExpectedClass, "Controller is not what we expect")
}
Run Code Online (Sandbox Code Playgroud)

Zel*_* B. 5

如果我以编程方式实例化并显示控制器,直接进入测试功能,当我检查On Top控制器时,我总是得到Storyboard根控制器而不是我刚刚实例化的控制器,好像我手动创建的控制器永远不会添加到应用程序层次结构中.

从您编写的代码中,您没有检查On Top控制器,但是您正在检查根视图控制器本身(它包含层次结构中的所有视图控制器,包括导航控制器),这就是为什么您总是得到故事板根视图控制器.要从视图控制器获得最顶层的控制器,您可以使用以下递归功能,该功能采用根视图控制器并返回其最顶层的控制器

func topMostController(rootViewController:UIViewController)->UIViewController{

    if let viewController = rootViewController as? UINavigationController{

        return topMostController(viewController.visibleViewController)
    }

    if let viewController = rootViewController.presentedViewController{

        return topMostController(viewController)
    }

    return rootViewController
}
Run Code Online (Sandbox Code Playgroud)

然后在您的测试功能中检查控制器该函数返回

func testController(){ 

// Instantiate a controller 
let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle(forClass: self.dynamicType))
let controller1 = storyBoard.instantiateViewControllerWithIdentifier("Controller1") as? ControllerOneViewController
controller1.loadView()

// Call a function that instantiates another controller 
controller1.pushAnotherController()

// Test that the current shown controller is what we expect... 
let rootController = UIApplication.sharedApplication().keyWindow?.rootViewController
XCTAssert(topMostController(rootController) == TheExpectedClass, "Controller is not what we expect")
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*lex 0

首先,您声明视图是否由导航控制器呈现并不重要。所以我创建了一个空应用程序,其中一个导航控制器作为初始控制器和两个视图控制器,第一个只是命名,ViewController第二个在我的情况下ViewControllerSecond是您的TheExpectedClass控制器。

首先要注意的是:如果使用导航控制器,显然根控制器将始终是导航控制器。那么让我们检查一下如果我们首先加载ViewController然后在其中推送会发生什么ViewControllerSecond

    let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle(forClass: self.dynamicType))
    let controllerSecond = storyBoard.instantiateViewControllerWithIdentifier("ViewControllerSecond") as? ViewControllerSecond

    controllerSecond?.loadView()
    self.navigationController?.pushViewController(controllerSecond!, animated: false)

    let navigationController = UIApplication.sharedApplication().keyWindow?.rootViewController as UINavigationController
    let currentController: AnyObject = navigationController.viewControllers[0]
    println(navigationController.viewControllers)
Run Code Online (Sandbox Code Playgroud)

您将看到它ViewControllerSecond已按其应有的方式推送到了 navigationController。