XCUITest类拆卸不删除该应用程序。但是,如果它的实例被拆除,则可以工作。我究竟做错了什么?

时间:2018-11-06 23:53:08

标签: swift xcode ui-automation xctest xcuitest

我遇到了一个类别为试图删除该应用程序的拆解,但无法识别app.terminate()。

class DeviceSettingsUtilities : UITestUtilities {
func removeApp(productName:String){
        print("in teardown")
        let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
        XCUIApplication().terminate() // this does nothing
        XCUIApplication(bundleIdentifier: "com.xxx.xxxx").terminate()//this does nothing too, but this works when called as an instance teardown
        sleep(5)
        springboard.activate()
        let icon = springboard.icons.matching(identifier: productName).firstMatch
// icon.exists is false when called as a class teardown
// icon.exists is true when called as an instance teardown
        if icon.exists {
            let iconFrame = icon.frame
            let springboardFrame = springboard.frame
            icon.press(forDuration:1.3)
            springboard.coordinate(withNormalizedOffset: CGVector(dx: ((iconFrame.minX + 3) / springboardFrame.maxX), dy:((iconFrame.minY + 3) / springboardFrame.maxY))).tap()
            sleep(5)
            springboard.buttons["Delete"].firstMatch.tap()
            sleep(5)
        }
        XCUIApplication().terminate()
    }

}

这在测试用例类拆解方法中被调用,如下所示

override class func tearDown() {
    super.tearDown()
    let deviceSettings = DeviceSettingsUtilities()
    deviceSettings.removeApp(productName: ProductName.rawValue)
}

这只是不删除应用程序,但是如果我将func tearDown()类更改为func tearDown(),它将毫无问题地删除该应用程序。不知道我在想什么。有什么建议吗?

3 个答案:

答案 0 :(得分:1)

这似乎是最新XCode 10中的错误。 声明为XCUIApplication.terminate()时,tearDown()class中似乎不起作用。

这可以通过两种方式解决:

1 /使用:

override func tearDown() {
    XCUIApplication().terminate()
    super.tearDown()
}

代替:

override class func tearDown(){...} 

2 /以不同方式终止应用程序(按主屏幕按钮,打开其他应用程序...)。但是,我将使用第一种方法。

还可以考虑将此问题报告给Apple,以便他们进行修复。

编辑:这与应用程序状态(XCUIApplication().state.rawValue)没有关系,因为它在测试和tearDown()4 = running foreground)中都是相同的。另外-官方文档说.terminate()将终止具有XCode调试会话的应用,但该调试会话在tearDown()中也处于活动状态。因此,这实际上可能是XCode中的错误。

答案 1 :(得分:1)

将代码放在类tearDown中时,不会重置应用程序,因为该方法仅在类中的所有测试完成后才运行。实例tearDown是放置每次测试后要运行的代码的最佳位置。

来自Apple's documentation

  

对于每个类,测试都是通过运行类设置方法开始的。对于每种测试方法,将分配该类的新实例并执行其实例设置方法。之后,它运行测试方法,然后运行实例拆卸方法。对于该类中的所有测试方法,都将重复此顺序。在类中运行完最后一个测试方法拆卸之后,Xcode将执行该类拆卸方法,然后移至下一个类。重复此序列,直到运行了所有测试类中的所有测试方法。

答案 2 :(得分:0)

我正在使用以下变通办法在类的最后一个测试用例之后终止应用程序。

class BaseClass: XCTestCase {

        static var LastTestCaseName: String = ""

        override class func setUp() {
            LastTestCaseName = defaultTestSuite.tests.last!.name
            super.setUp()
        }

        override func tearDown() {
            let app = XCUIApplication()
            if BaseClass.LastTestCaseName == testRun?.test.name {
                app.terminate()
            }
        }
    }