从代码进行故事板 UI 测试

Posted

技术标签:

【中文标题】从代码进行故事板 UI 测试【英文标题】:Storyboard UI testing from code 【发布时间】:2013-04-14 06:21:08 【问题描述】:

我有一个 ios 应用程序,我想通过代码测试它的 UI(使用单元测试)。我想模仿用户的活动和故事板活动:点击按钮,点击 barbutton,写入文本字段,执行 segue。

我对序列有疑问。我在 NavigationController 中有一个 TableViewConrtoller。首先,如何从代码中访问 TableViewController?

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
    UINavigationController *nav = [storyboard instantiateInitialViewController];
    GoodHabitsViewController *good = [nav.viewControllers objectAtIndex:0];

    NSLog(@"%@", good.addButton.title);

    [good performSegueWithIdentifier:@"AddGoodHabitSegue" sender:good];

NSLog写入正确值,按钮标题为“add”,log中出现“add”。 但是在 performSequeWithIdentifier 之后会出现以下警告:

Warning: Attempt to present <AddGoodHabitViewController: 0x74c8310> on <UINavigationController: 0x764e120> whose view is not in the window hierarchy!

如何执行序列,如何推送 addButton (UIBarButton) 以及如何引用 AddGoodHabitViewController(segue 指向的位置)。

【问题讨论】:

【参考方案1】:

有两种测试可以在 OCUnit 平台上运行 - 所谓的“应用程序”测试和所谓的“逻辑”测试。

只有“应用程序”测试才能让您练习 UIViewControllers、UIViews 等。如果您在创建项目时指定了“创建测试目标”,它将使用“应用程序”样式。否则,稍后添加测试集目标,默认情况下,使用“逻辑”样式。为了将现有的测试目标转换为使用“应用程序”测试,TwoBit Labs 提供了一个不错的方法:guide

另一种练习代码直至视图控制器和视图的方法是使用Cedar BDD test framework。 Cedar 测试在 iOS 应用程序内部运行,因此除了能够测试 ViewControllers 和 Views 之外,它还可以在设备或模拟器上进行测试。

UIAutomation 允许通过驱动 UI 本身(而不是执行 UI 代码)来执行自动化功能测试。 UIAutomation 的问题是,据我所知,它不可能从命令行执行它,因此很难包含在自动化测试套件中 - 一个由持续集成服务器运行的测试套件。 . . .有人可能会使用 Automator.app 或类似工具来解决此问题,但到目前为止还没有人这样做。

Calabash 是另一个很棒的 UI 测试框架,可以从命令行运行,因此不受我上面描述的限制,wrt UIAutomation。

请记住,自动化功能测试与在代码级别测试 UIViewController 和 View 是两个截然不同的事情。后者当然有价值,只需要正确设置捆绑加载器即可。

更新:在 Xcode 5+ 的最新版本中,应用程序样式的测试是默认设置。

【讨论】:

比我的回答好多了。不错。【参考方案2】:

正如错误消息指出的那样,问题在于您试图在 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
    //
    XCTAssertEqualObjects(viewController.presentedViewController.title, @"Second");


【讨论】:

你是如何测试 push segues 的? @fatuhoku 我试驾一切。我唯一无法测试的是来自 IB 中定义的UITableView 单元格的segues。除此之外,一切都是可测试的。包括推送 segues。 这太不可思议了!我还发现 push segues 是不可能在表视图上测试的,因为它们似乎没有激活 presentedViewControllermalarkey。我希望可以以同样的方式测试集合视图。 UITableViewCell IB segues 的问题在于不可能以编程方式触发它们。所以,我用代码来做。至于presentedViewController,我对此没有任何问题。也谢谢你的点赞!如今,我正在测试 100% 的代码和 IB,零异常。我还在考虑围绕纯功能核心构建应用程序的想法,测试起来非常简单。 你有一个 Github 代码,你可以在其中进行测试驾驶吗?我遇到了 UICollectionView 的障碍,很想看看你是怎么做到的。【参考方案3】:

单元测试(即通过 Xcode 模板向项目添加单元测试时获得的那些)不适用于测试 UI。您需要查看UI Automation,它允许您使用 javascript 编写 UI 操作。

【讨论】:

我检查了 UI 自动化,但我需要 Objective-c UI 测试工具。 (我将从模型中生成代码) 据我所知,没有。我不明白你说的生成代码是什么意思。【参考方案4】:

查看 KIF。这听起来几乎是您所需要的:

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

它是一个基于 Objective-C 的 UI 测试框架,与内置于应用程序的 Accessibility 框架集成(就像 UI 自动化所做的那样)。

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

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

希望您能找到解决方案!

【讨论】:

以上是关于从代码进行故事板 UI 测试的主要内容,如果未能解决你的问题,请参考以下文章

故事板中的子类 viewController 并以编程方式从子类更改 UI

在故事板xcode中直接从视图控制器警告启动的Segues

iOS:如何滑动列表项以显示命令(带故事板)

调整图像大小以适合 xcode 故事板中的 Ui 图像视图

框架中的自定义 ui 组件未呈现到故事板

Swift pagecontroller 故事板 UI 对象与 UIPageviewcontroller 连接