14

我正在构建一个通用的 iPhone/iPad 应用程序,并且 UI 在某些情况下明显不同(即在 iPhone 上,我们使用带有 TableViews 的 Master/Detail 范例,而在 iPad 上,我们使用带有包含详细信息的单元格的 CollectionView) .

因为接口是如此不同,它改变了视图控制器的单元测试的构建方式。在集合视图中,我们必须进行测试以确保单元格正确构建并包含所有详细信息,而在 iPhone 上,我们需要两组测试 - 一组用于主列表,一组用于详细信息屏幕。

所以我的问题是,在使用 Xcode 5 和 XCTest 框架构建的通用应用程序中,您能否针对要在特定物理设备上运行的单个单元测试用例/类?

我在这里遇到了一个类似的问题 - iOS 单元测试通用应用程序- 但提问者有不同的意图并且使用的是旧技术。

我还看到建议对UserInterfaceIdiom的单个测试函数进行检查,但这似乎很粗糙。理想情况下,会有一个注释可以指定在特定设备上运行的特定测试,或者能够为特定设备指定整个测试类。

提前感谢您的建议。

- 编辑 -

@TommieC 引导我走上似乎是适当的道路,如果有一点手册的话。我创建了两种新的测试特定方案,一种用于手机大小的设备,另一种用于平板电脑大小的设备。在这些方案中,我编辑了测试部分并添加了核心测试以及特定于设备的测试。

然后我让 jenkins 执行两个构建步骤,针对适当的设备来测试特定的方案。这种方法的缺点是两个构建步骤。但是,我计划拆分 jenkins 作业并在 2 个从站上运行它,每个从站连接适当的设备以并行化测试。

AFAIK 这也将是 Xcode Build Services 友好的,因为它也基于项目中的方案工作。真的太糟糕了,XCTest 没有为此内置更优雅的东西,考虑到在新设备类型(手表/电视/吹风机/等)出现的情况下,这并不能很好地扩展。

4

3 回答 3

2

要针对特定​​于设备的测试,需要编辑项目的方案。在产品 > 方案 > 编辑方案下,可以选择为每个设备选择特定于设备的测试。

方案编辑器

于 2013-10-28T15:58:10.727 回答
1

这是我提出的解决方案。

将您的测试分成 iPhone 特定和 iPad 特定的测试。

现在为 iPhone 或 iPad 添加一个新的 Target (Cocoa Touch Unit Testing Bundle)。如果您已经编写了许多常见的测试,那么复制您当前的测试目标可能会更加谨慎。

现在确保您的 iPhone 特定测试类仅包含在您的 iPhone 测试目标中,方法是单击导航器中的类,然后打开实用程序面板。您可以使用 Target Membership 复选框来设置您的班级所属的目标。

目标会员面板

要对此进行扩展,您可以为两个目标添加不同的方案,以更快地运行测试。

于 2013-10-26T00:10:09.097 回答
0

我正在寻找做同样的事情并遇到了这个旧帖子。我的解决方案涉及将特定设备测试命名为以“Pad”或“Phone”结尾,然后过滤测试列表以包含当前设备的测试:

class MyTests: XCTestCase {
    override class var defaultTestSuite: XCTestSuite {
        let suite = XCTestSuite(forTestCaseClass: MyTests.self)

        let newSuite = XCTestSuite(name: "MyTests")
        for test in suite.tests {
            // Name is of the form "-[MyTests test*]"
            if test.name.hasSuffix("Pad]") {
                // iPad only test
                if UIDevice.current.userInterfaceIdiom == .pad {
                    newSuite.addTest(test)
                }
            }
            else if test.name.hasSuffix("Phone]") {
                // iPhone only test
                if UIDevice.current.userInterfaceIdiom == .phone {
                    newSuite.addTest(test)
                }
            }
            else {
                // Can run on both devices
                newSuite.addTest(test)
            }
        }

        return newSuite
    }

    func testAll() { // All devices test }
    func testOnlyPad() { // iPad only test }
    func testOnlyPhone() { // iPhone only test }
}
于 2019-10-04T21:34:55.143 回答