首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何拖放Xcode-ui-testing的外部项

如何拖放Xcode-ui-testing的外部项
EN

Stack Overflow用户
提问于 2020-07-14 05:31:47
回答 2查看 191关注 0票数 1

在我的应用程序中,我允许用户将项目从Finder (或任何其他基于URL的文件来源)拖放到我的应用程序中。我想要做的是添加一种机制,允许我在Xcode UI测试中对此进行测试。

我可以看到如何使用XCUIElement.press(forDuration:thenDragTo:)来测试源和目标在应用程序中的拖放,但我一直无法找到一种方法来测试拖放源是否在应用程序之外。

在一个相关的测试中,我测试了应用程序的复制和粘贴部分,方法是设置要粘贴到NSPasteboard.general中的字符串,然后使用XCUIElement.typeKey("v", modifierFlags: .command)将其粘贴到所需的元素中。这有点不太理想,因为它依赖于Command-v实际上是作为粘贴命令实现的,但这种情况不太可能改变,所以我的需要是可以接受的。(实际上,我已经编写了一个XCUIElement.paste(_ s: String)扩展,它使我可以轻松地将其添加到测试中。)

我相信拖放也是使用NSPasteboard进行通信的,所以只要稍微研究一下底层机制,我就应该能够将对象设置到正确的粘贴板中,就像对剪切和粘贴所做的那样。我相当确定我能弄清楚这一部分。但我还没有想出如何执行实际的drop。

我的目标是创建一个XCUIElement.drop(_ url),将正确的“proper .file-url”对象设置到正确的粘贴板中,然后模拟/执行拖放到元素中。

有什么想法吗?

我应该注意到,我已经尝试了以下两个项目:

首先,我确实使用了Xcode记录功能来尝试记录拖放操作,并查看它会给我带来什么事件。不幸的是,它完全没有记录任何东西。

其次,我确实有一个基于菜单的替代方案,用户可以通过文件选择器选择一个文件。因此,如果我可以模拟文件选择,这将是一个适合我的目的的测试替代方案。不幸的是,我在这条道路上也没有取得任何进展。当我使用Xcode记录事件时,它记录了菜单选择,对话框中实际上没有执行任何操作。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-14 17:40:30

根据您的评论,我建议您阅读这篇文章的文档部分https://developer.apple.com/documentation/xctest/xcuiapplication

请注意init(bundleIdentifier: String)init(url: URL)方法。这些允许您与目标应用程序之外的应用程序进行交互。

然后,您可以使用XCUIElement.press(forDuration:thenDragTo:)

代码语言:javascript
复制
import XCTest
import XCTApps
import ScreenObject

let notes = XCTApps.notes.app
let photos = XCTApps.photos.app

class Tests: XCTestCase {
    func testDragAndDrop() {
        photos.launch()
        notes.launch()
        photos.images.lastMatch.press(forDuration: 1, thenDragTo: notes.textViews["Note Body Text View"])
    }
}

在这个例子中,我使用了XCTApps,因为我不想记住或者谷歌包标识符:D

https://github.com/rzakhar/XCTApps

票数 1
EN

Stack Overflow用户

发布于 2020-07-14 07:45:37

好吧,我还没有想出我的问题的答案(如何测试拖放),但我已经为我的测试提出了一个可以接受的变通办法。

特别是,当我更多地考虑粘贴板时,我意识到如果我允许用户将文件拖放到我的应用程序中,那么我也应该允许他们将文件剪切和粘贴到应用程序中。

一旦我意识到这一点,那么通过粘贴URL而不是拖放URL来测试我的应用程序的必要功能就是一个相当简单的过程。这有一个额外的好处,那就是我可以将必要的测试文件添加到我的测试包中,使所有内容保持良好的自包含状态。

为此,我在XCUIElement扩展中添加了以下函数:

代码语言:javascript
复制
extension XCUIElement {
    func paste(url: URL) {
        precondition(url.isFileURL, "This must be a file URL to match the pasteboard type.")
        let pasteboard = NSPasteboard.general
        pasteboard.clearContents()
        pasteboard.setString(url.absoluteString, forType: .fileURL)
        click()
        typeKey("v", modifierFlags: .command)
    }
}

然后在我的测试代码中添加以下代码来触发事件:

代码语言:javascript
复制
let mainWindow = app.windows[/*...my main window name goes here...*/]
let testBundle = Bundle(for: type(of: self))
let fileURL = testBundle.url(forResource: "Resources/simple", withExtension: "json")
mainWindow.paste(url: fileURL!)

诚然,这并不实际测试拖放,但它确实测试了我的代码的相同部分,因为在我的AppDelegate中,我的onPaste操作方法调用与我的performDrop方法相同的底层方法。

我将等待几天,看看是否有人提出了实际问题的答案(因为我仍然会发现这是有用的),但如果没有人这样做,我会接受我自己的答案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62884594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档