XCTest Swift - 如何更快或更精确地滑动?

时间:2016-09-01 21:02:05

标签: ios swift xcode xctest

我在XCTest中使用Swift进行测试,我试图在Feed中滑动,直到满足条件。我正在使用swipeUp(),但问题在于它的行为就像人类轻扫一样,并且当它放开时会有这种痛苦的动画减速。在减速动画完成之前,它不会再次尝试滑动。此外,该方法不带任何参数。我想看看是否有类似Calabash的东西或甚至拍摄Androids Espresso,其中有swipeUp(fast)swipeUp(medium)甚至swipeUp(x0,y200)等滑动方法的属性。

以下是我在代码中尝试做的事情:

    func scrollDownUntilYouFindSomething() {
    while !findingSomehting.exists {
        app.swipeUp()
    }
}

很简单,但XCUIApplication中的swipeUp()速度很慢。我希望能够精确地滑动甚至通过坐标。我尝试使用从Replicate pull to refresh in XCTest UI testing

获取的坐标方法

但是当它进入循环时同样缓慢。

4 个答案:

答案 0 :(得分:11)

我根据Bharathram C给出的优秀答案写了一个扩展名。

我发现它比XCUIElement.swipeUp()

更轻松一击
//  XCUIElement+GentleSwipe.swift

import Foundation
import XCTest

extension XCUIElement
{
    enum direction : Int {
        case Up, Down, Left, Right
    }

    func gentleSwipe(_ direction : direction) {
        let half : CGFloat = 0.5
        let adjustment : CGFloat = 0.25
        let pressDuration : TimeInterval = 0.05

        let lessThanHalf = half - adjustment
        let moreThanHalf = half + adjustment

        let centre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: half))
        let aboveCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: lessThanHalf))
        let belowCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: moreThanHalf))
        let leftOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: lessThanHalf, dy: half))
        let rightOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: moreThanHalf, dy: half))

        switch direction {
        case .Up:
            centre.press(forDuration: pressDuration, thenDragTo: aboveCentre)
            break
        case .Down:
            centre.press(forDuration: pressDuration, thenDragTo: belowCentre)
            break
        case .Left:
            centre.press(forDuration: pressDuration, thenDragTo: leftOfCentre)
            break
        case .Right:
            centre.press(forDuration: pressDuration, thenDragTo: rightOfCentre)
            break
        }
    }
}

答案 1 :(得分:7)

是的,我们可以在Swift中进行基于坐标的滑动。我们可以使用pressForDuration(duration,thenDragToElement:XCElement)创建自己的滑动操作。请参阅下面的示例。

为此,我们需要

  1. 视图中的参考元素。(在必须执行滑动操作的部分中选择一个,它不应该是可拖动的元素。)
  2. 关于参考元素的开始坐标。
  3. 关于参考元素的结束坐标/ XCUIElement。
  4. 然后我们可以有一个类似于下面的函数(在Swift 3中)

    func customSwipe(refElement:XCUIElement,startdelxy:CGVector,enddeltaxy: CGVector){
          let swipeStartPoint = refElement.coordinate(withNormalizedOffset: startdelxy)
          let swipeEndPoint = refElement.coordinate(withNormalizedOffset: enddeltaxy)
          swipeStartPoint.press(forDuration: 0.1, thenDragTo: swipeEndPoint)
    
    }
    

    如果 startdelxy 为(0.0,0.0)且 enddeltaxy 为(0.0,-ve),则滑动将从 refElement 向上移动。如果 enddeltaxy 是(0.0,+ ve),则滑动将下降。这是因为我们的参考元素将是原点,X是+ ve向右,Y是+ ve低于我们的参考元素。从较小的Y值开始(比如-0.75)并根据需要进行更改。更多的差异,更长的滑动。

    swipeStartPoint swipeEndPoint 可以替换为元素(如果在视图中存在)。通常,对于 swipeEndPoint ,我们可以在导航栏中搜索swipeUp操作的元素。此外,更改X可以在左右方向上为我们提供customSwipes。

    至于刷卡速度,我不知道任何API可以比默认速率更快/更慢刷卡。

答案 2 :(得分:5)

已将the first answer更新为Swift 4。

extension XCUIElement {
    enum Direction: Int {
        case up, down, left, right
    }

    func gentleSwipe(_ direction: Direction) {
        let half: CGFloat = 0.5
        let adjustment: CGFloat = 0.25
        let pressDuration: TimeInterval = 0.05

        let lessThanHalf = half - adjustment
        let moreThanHalf = half + adjustment

        let centre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: half))
        let aboveCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: lessThanHalf))
        let belowCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: moreThanHalf))
        let leftOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: lessThanHalf, dy: half))
        let rightOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: moreThanHalf, dy: half))

        switch direction {
        case .up:
            centre.press(forDuration: pressDuration, thenDragTo: aboveCentre)
        case .down:
            centre.press(forDuration: pressDuration, thenDragTo: belowCentre)
        case .left:
            centre.press(forDuration: pressDuration, thenDragTo: leftOfCentre)
        case .right:
            centre.press(forDuration: pressDuration, thenDragTo: rightOfCentre)
        }
    }
}

答案 3 :(得分:0)

  

我试图将gentleSwipe函数重构为目标元素。以下   重构焦点以达到目标元素。我们可以在   swipeUp函数,它将调用gentleSwipe,这将有助于我们   达到目标元素。我希望它也会对其他人有所帮助。

以下是代码:

public func swipeUp(to element: XCUIElement) {
    while !(elementIsWithinWindow(element: element)) {
           XCUIApplication().gentleSwipe(.up)
    }
}

private func elementIsWithinWindow(element: XCUIElement) -> Bool{
    guard element.exists && element.isHittable else {return false}
    return true
}

enum direction : Int {
    case up, down, left, right
}

func gentleSwipe(_ direction : direction) {
    let half : CGFloat = 0.5
    let adjustment : CGFloat = 0.25
    let pressDuration : TimeInterval = 0.05

    let lessThanHalf = half - adjustment
    let moreThanHalf = half + adjustment

    let centre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: half))
    let aboveCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: lessThanHalf))
    let belowCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: moreThanHalf))
    let leftOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: lessThanHalf, dy: half))
    let rightOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: moreThanHalf, dy: half))

    switch direction {
    case .up:
        centre.press(forDuration: pressDuration, thenDragTo: aboveCentre)
        break
    case .down:
        centre.press(forDuration: pressDuration, thenDragTo: belowCentre)
        break
    case .left:
        centre.press(forDuration: pressDuration, thenDragTo: leftOfCentre)
        break
    case .right:
        centre.press(forDuration: pressDuration, thenDragTo: rightOfCentre)
        break
    }
}

通话提示

app.swipeUp(收件人:“ element”)