Ios 我可以用KIF检查屏幕上是否存在视图吗?

Ios 我可以用KIF检查屏幕上是否存在视图吗?,ios,kif,Ios,Kif,我正在做一个“每一步之前”的步骤,我想做的步骤注销。在我尝试触摸某个元素之前,我找不到任何关于检查该元素是否存在的信息,如果该元素不存在,请执行其他操作。是否可以在没有对我要检查的对象的引用的情况下使用KIF执行此操作 比如: if([tester elementExistsWithAccesibilityLabel:@"backButton"]) { [tester tapViewWithAccessibilityLabel:@"backButton"]; } else { [

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

比如:

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

您可以尝试以下方法:

@try {
   if([tester waitForViewWithAccessibilityLabel:@"backButton"])
   {
      [tester tapViewWithAccessibilityLabel:@"backButton"];
   }
@catch (NSException *exception )
{
   [tester tapViewwithAccesibilityLabel:@"Logout"];
}
@finally 
{
   NSLOG(@"User logged out.");
}

我建议尝试这种方法:

if([[[UIApplication sharedApplication] keyWindow] accessibilityElementWithLabel:@"backButton"] != nil) {
     [tester tapViewWithAccessibilityLabel:@"backButton"];
} else {
     [tester tapViewWithAccessibilityLabel:@"Logout"];
}

我做的这个函数似乎是在紧要关头完成的,但是如果多个集成测试同时依赖于全局默认超时,它会有一些问题。到目前为止,似乎对我有效

static CGFloat CPKIFDefaultTimeout = 2

- (BOOL)elementExistsWithAccessibilityLabel:(NSString *)accessibilityLabel {
    [KIFTestActor setDefaultTimeout:0.0];
    BOOL result = [tester waitForViewWithAccessibilityLabel:accessibilityLabel] ? YES : NO;
    [KIFTestActor CPKIFDefaultTimeout];
    return result;
}

这些方法可以奏效。将它们添加到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;
}
#导入“UIApplication kifadeditions.h”
#导入“UIAccessibilityElement kifaditions.h”
#导入“NSError kifaditions.h”
-(BOOL)existsViewWithAccessibilityLabel:(NSString*)标签
{
UIView*view=nil;
UIAccessibilityElement*元素=零;
return[self-existsaccessibilitylement:&element-view:&view with-label:label-value:nil traits:UIAccessibilityTraitNone-tappable:YES];
}
-(BOOL)existsaccessibilitylement:(uiaccessibilitylement**)元素视图:(out UIView**)带标签的视图:(NSString*)标签值:(NSString*)值特征:(UIAccessibilityTraits)特征可点击:(BOOL)必须可点击
{
KIFTestStepResult(^executionBlock)(NSError**)=^(NSError**error){
return[UIAccessibilityElement accessibilityElement:element视图:带标签的视图:标签值:值特征:特征tappable:mustBeTappable错误:error]?kiftestStepResultAccess:KIFTestStepResultWait;
};
NSDate*开始日期=[NSDate日期];
KIFTestStepResult结果;
n错误*错误=nil;
NSTimeInterval超时=10.0;
while((result=executionBlock(&error))==kifteststepsresultwait&-[startDate timeIntervalSinceNow]

它对我很有效。

好吧,这些对我都不起作用。。。然而,我有一个解决办法

结帐

我所做的就是使用KIF的代码,并删除了他们的错误检查——这对我来说很有吸引力


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

如果有人仍在寻找答案,KIF中有一系列方法可以执行
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;
如果您正在使用可访问性标识符添加(
pod'KIF/IdentifierTests'
),还有一种非常方便的等效方法:
-(BOOL)尝试使用accessibilityIdentifier查找视图:(NSString*)accessibilityIdentifier

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

    }
}

如果使用Swift,您只需使用
viewTester()。tryFindingView()


这不起作用,因为异常首先由我的KIF代码处理,并且永远不会到达代码中的
@try
块。这对我来说很有效,但请记住将其放在
@autorelease{…}
中。添加了必要的头导入以使代码正确编译。这不适用于Xocde8.2。测试在以下行停止:tester waitForViewWithAccessibilityLabel:accessibilityLabel。如果视图位于视图层次结构中,但在显示另一个VC时当前无法在屏幕上查看,则此操作不起作用。
if viewTester().usingLabel("backButton").tryFindingView() {
    // back button exists
    viewTester().usingLabel("backButton").tap()
} else {
    // back button does not exist
    viewTester().usingLabel("Logout").tap()
}