单元测试用例视图控制器崩溃 swift

Unit test case view controller crash swift

我正在为我的 iOS 应用程序中的视图控制器编写单元测试用例。我正在尝试测试涉及 IBOutlets 的 UI 元素是否不是下面代码中的 nil。

class ClientsViewControllerTests: XCTestCase {

var clientsVC: ClientsTableViewController?

override func setUp() {
    super.setUp()

    let storyboard = UIStoryboard(name: "Clients", bundle: nil)

    clientsVC = storyboard.instantiateInitialViewController() as? ClientsTableViewController

    if let vc = clientsVC?{
        vc.loadView()
    }
}

override func tearDown() {

    super.tearDown()
    clientsVC = nil
}

func testClientViewControllerNotNil(){

    XCTAssertNotNil(clientsVC, "view controller cannot be nil")
}

我测试失败并输出"view controller cannot be nil"

我没看懂why.However,下面的测试通过了:

func testStoryBoard(){
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    var vc = storyboard.instantiateViewControllerWithIdentifier("MainVC") as UIViewController
    XCTAssertNotNil(vc,"Storyboard is not connected with a viewcontroller")

但我需要在第一种方法中执行此操作,因为我想测试特定 viewController 的 IBOutlet 绑定,例如:

XCAssertNotNil(vc.sendButton, "Send button is nil")

请指导我测试失败的原因以及如何测试 ViewController 中的插座绑定和动作绑定

在setUp方法中打一个断点来检查clientsVC对象是否初始化。尝试使用 instantiateViewControllerWithIdentifier("Client") 方法进行初始化。

请记住,setUp 和 tearDown 方法将分别在 class 中的每个测试方法执行之前和之后被调用。

经过多次试错,我们发现以下代码对我们有用。问题是我们在 bundle 参数中传递了 'nil' 值。当它被替换为以下行时,它开始工作。 bundle: NSBundle(forClass: self.dynamicType))

工作代码:

let storyboard = UIStoryboard(name: "Clients", bundle: NSBundle(forClass: self.dynamicType))

var vc = storyboard.instantiateViewControllerWithIdentifier("ClientsVCTable") as ClientsTableViewController

vc.loadView()

XCTAssertNotNil(vc.clientSearchBar,"Not Nil")

同样适用于 IBActions:

let storyboard = UIStoryboard(name: "Login", bundle: NSBundle(forClass: self.dynamicType))

var vc = storyboard.instantiateViewControllerWithIdentifier("LoginViewController") as LoginViewController

vc.loadView()

let actions : NSArray = vc.signInButton.actionsForTarget(vc, forControlEvent: UIControlEvents.TouchUpInside)!

XCTAssertTrue(actions.containsObject("login"), "IBActions not found")