XCTest 如何执行 segue 呈现模态视图并测试presentedViewController

Posted

技术标签:

【中文标题】XCTest 如何执行 segue 呈现模态视图并测试presentedViewController【英文标题】:XCTest how to perform segue that present a modal view and test presentedViewController 【发布时间】:2013-12-17 10:49:09 【问题描述】:

我试图测试一个可以呈现视图控制器的 segue。但是,总是失败。如何等待segue完成?请帮忙。

[self.viewController performSegueWithIdentifier:@"mySegueName" sender:self.viewController];
XCTAssertNotNil(self.viewController.presentedViewController, @"Failed to show modal view");

【问题讨论】:

【参考方案1】:

问题是您试图在UIViewController 上呈现,其视图不在UIWindow 层次结构中。这是我的解决方案:

- (void)testExample 

    //
    // Arrange
    // Storyboard
    //
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

    //
    // Arrange
    // View Controller
    //
    UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
    [UIApplication sharedApplication].keyWindow.rootViewController = viewController;

    //
    // Act
    //
    [viewController performSegueWithIdentifier:@"ModalSegue" sender:nil];

    //
    // Assert
    //
    XCTAssertNotNil(viewController.presentedViewController);


【讨论】:

【参考方案2】:

提供一个 Swift 3.0 答案,它也使用 Quick/Nimble 框架并通过在视图空间中“点击”执行 Segue 的按钮来执行 Segue。

        // Note: there's also a beforeEach  that sets up the mainViewController
        describe("navigation")  
        beforeEach 
            // Access the view to trigger MainViewController.viewDidLoad().
            let _ = mainViewController.view
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let window = appDelegate.window
            window?.rootViewController = mainViewController
        

        describe("the views navigationBar", closure: 
            describe("left bar button item", closure:  
                context("when pressed", closure:  
                    it("displays SomeViewController", closure: 
                        let item = mainViewController.navigationBar.topItem
                        let addItem = item?.leftBarButtonItem
                        tap(addItem!)
                        expect(mainViewController?.presentedViewController).toEventually(beAnInstanceOf(SomeViewController.self))
                    )
                )
            )
        )
    

参考 tap() 方法:

    func tap(_ barButtonItem: UIBarButtonItem) 
        let _ = barButtonItem.target?.perform(barButtonItem.action, with: barButtonItem)
    

【讨论】:

【参考方案3】:

您是否考虑过使用 KIF?它是一个基于 Objective-C 的 UI 测试框架,它与内置于应用程序的 Accessibility 框架集成(就像 UI 自动化所做的那样)。这使得它非常适合通过常规测试框架进行 UI 测试。

https://github.com/kif-framework/KIF

或者按照这个教程来确保它是你想要的:

http://www.raywenderlich.com/61419/ios-ui-testing-with-kif

希望您能找到解决方案!

【讨论】:

以上是关于XCTest 如何执行 segue 呈现模态视图并测试presentedViewController的主要内容,如果未能解决你的问题,请参考以下文章

如何在模态呈现的视图控制器上执行呈现模态序列?

如何从 appdelegate 呈现和关闭模态视图?

如何在触发退出 segue 之前执行操作?

iOS:模态视图控制器如何记住它的属性?

在 Xcode 中执行 segue 后如何关闭视图控制器?

使用 ABPeoplePickerNavigationController 后展开 segue 崩溃