17

我正在做一个“在每个”步骤之前,我想做一些步骤来注销。在尝试触摸元素之前,我找不到任何关于检查元素是否存在的信息,如果它不存在,请执行其他操作。是否可以在不引用我要检查的对象的情况下使用 KIF 执行此操作?

就像是:

if([tester elementExistsWithAccesibilityLabel:@"backButton"])
{
    [tester tapViewWithAccessibilityLabel:@"backButton"];
}
else
{
    [tester tapViewwithAccesibilityLabel:@"Logout"];
}
4

8 回答 8

19

我建议尝试这种方法:

if([[[UIApplication sharedApplication] keyWindow] accessibilityElementWithLabel:@"backButton"] != nil) {
     [tester tapViewWithAccessibilityLabel:@"backButton"];
} else {
     [tester tapViewWithAccessibilityLabel:@"Logout"];
}
于 2014-02-10T06:53:45.987 回答
5

These methods do the trick. Add them to a category for KIFUITestActor.

#import "UIApplication-KIFAdditions.h" 
#import "UIAccessibilityElement-KIFAdditions.h"
#import "NSError-KIFAdditions.h"

- (BOOL)existsViewWithAccessibilityLabel:(NSString *)label
{
    UIView *view = nil;
    UIAccessibilityElement *element = nil;
    return [self existsAccessibilityElement:&element view:&view withLabel:label value:nil traits:UIAccessibilityTraitNone tappable:YES];
}

- (BOOL)existsAccessibilityElement:(UIAccessibilityElement **)element view:(out UIView **)view withLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits tappable:(BOOL)mustBeTappable
{
    KIFTestStepResult (^executionBlock)(NSError **) = ^(NSError **error) {
        return [UIAccessibilityElement accessibilityElement:element view:view withLabel:label value:value traits:traits tappable:mustBeTappable error:error] ? KIFTestStepResultSuccess : KIFTestStepResultWait;
    };

    NSDate *startDate = [NSDate date];
    KIFTestStepResult result;
    NSError *error = nil;
    NSTimeInterval timeout = 10.0;

    while ((result = executionBlock(&error)) == KIFTestStepResultWait && -[startDate timeIntervalSinceNow] < timeout) {
        CFRunLoopRunInMode([[UIApplication sharedApplication] currentRunLoopMode] ?: kCFRunLoopDefaultMode, 0.1, false);
    }

    if (result == KIFTestStepResultWait) {
        error = [NSError KIFErrorWithUnderlyingError:error format:@"The step timed out after %.2f seconds: %@", timeout, error.localizedDescription];
        result = KIFTestStepResultFailure;
    }

    return (result == KIFTestStepResultSuccess) ? YES : NO;
}

It works for me very well.

于 2014-02-26T14:08:53.480 回答
3

In case anyone is still looking for an answer, there is a family of methods in KIF that does just that KIFUITestActor-ConditionalTests.h:

- (BOOL)tryFindingViewWithAccessibilityLabel:(NSString *)label error:(out NSError **)error;

- (BOOL)tryFindingViewWithAccessibilityLabel:(NSString *)label traits:(UIAccessibilityTraits)traits error:(out NSError **)error;

- (BOOL)tryFindingViewWithAccessibilityLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits error:(out NSError **)error;

- (BOOL)tryFindingTappableViewWithAccessibilityLabel:(NSString *)label error:(out NSError **)error;

- (BOOL)tryFindingTappableViewWithAccessibilityLabel:(NSString *)label traits:(UIAccessibilityTraits)traits error:(out NSError **)error;

- (BOOL)tryFindingTappableViewWithAccessibilityLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits error:(out NSError **)error;

- (BOOL)tryFindingAccessibilityElement:(out UIAccessibilityElement **)element view:(out UIView **)view withIdentifier:(NSString *)identifier tappable:(BOOL)mustBeTappable error:(out NSError **)error;

- (BOOL)tryFindingAccessibilityElement:(out UIAccessibilityElement **)element view:(out UIView **)view withElementMatchingPredicate:(NSPredicate *)predicate tappable:(BOOL)mustBeTappable error:(out NSError **)error;

If you're using the Accessibility Identifier additions (pod 'KIF/IdentifierTests') there's also the very handy equivalent method: - (BOOL) tryFindingViewWithAccessibilityIdentifier:(NSString *) accessibilityIdentifier;

于 2016-01-27T16:34:52.700 回答
2

对于迅捷3:

/** return true when the view is found */
func searchForElement(_ label:String) -> Bool{
    do {
        try tester().tryFindingView(withAccessibilityLabel: label)
        return true
    } catch {
        return false

    }
}
于 2017-02-13T10:40:41.080 回答
1

你可以尝试这样的事情:

@try {
   if([tester waitForViewWithAccessibilityLabel:@"backButton"])
   {
      [tester tapViewWithAccessibilityLabel:@"backButton"];
   }
@catch (NSException *exception )
{
   [tester tapViewwithAccesibilityLabel:@"Logout"];
}
@finally 
{
   NSLOG(@"User logged out.");
}
于 2013-10-03T13:32:56.287 回答
0

好吧,这些都不适合我......但是我有一个解决方案

检查这个要点。

我所做的是采用 KIF 的代码,只是删除了他们的错误检查——对我来说就像一个魅力。

当它找不到元素时,它不会使您的测试失败!

于 2014-05-13T10:34:49.033 回答
0

我制作的这个函数似乎可以在紧要关头解决问题,但是如果多个集成测试同时依赖于全局默认超时,则会出现一些问题。到目前为止,似乎对我有用。

static CGFloat CPKIFDefaultTimeout = 2

- (BOOL)elementExistsWithAccessibilityLabel:(NSString *)accessibilityLabel {
    [KIFTestActor setDefaultTimeout:0.0];
    BOOL result = [tester waitForViewWithAccessibilityLabel:accessibilityLabel] ? YES : NO;
    [KIFTestActor CPKIFDefaultTimeout];
    return result;
}
于 2014-02-11T15:26:11.480 回答
0

如果使用 Swift,您可以简单地使用viewTester().tryFindingView()

if viewTester().usingLabel("backButton").tryFindingView() {
    // back button exists
    viewTester().usingLabel("backButton").tap()
} else {
    // back button does not exist
    viewTester().usingLabel("Logout").tap()
}
于 2020-02-07T10:47:18.270 回答