KIF 3.9.0

KIF 3.9.0

测试已测试
Lang语言 Obj-CObjective C
许可证 NOASSERTION
发布最后发布2024年5月

Tony MannMike LupoBrian NickelDerek OstranderJustin MartinHarley CooperSteve Sun维护。



KIF 3.9.0

  • Michael Thole、Eric Firestone、Jim Puls 和 Brian Nickel 编写

Build Status Carthage compatible CocoaPod Version

重要提示!即使KIF用于测试您的UI,您也需要将其添加到单元测试目标中,而不是UI测试目标中。KIF的神奇之处在于它允许您从单元测试中驱动UI,并享受所有进程测试的优势。

KIF iOS集成测试框架

KIF(Keep It Functional的缩写)是一个iOS集成测试框架,通过利用操作系统为有视觉障碍的人提供的可访问性属性,可以轻松自动化iOS应用程序。

KIF使用标准XCTest测试目标构建和执行测试。测试在主线程中同步进行(运行运行循环以强制时间流逝),允许更复杂的逻辑和组合。这也允许KIF利用Xcode测试导航器、命令行构建工具和Bot测试报告。

KIF使用未经记录的Apple API。这对于大多数iOS测试框架都是真实的,但在测试目的下是安全的。但重要的是,KIF不要出现在生产代码中,因为这会导致您的应用程序提交被苹果公司拒绝。按照以下说明确保KIF正确配置您的项目。

支持Xcode 11.6和iOS 11-13,如果需要支持更早版本,请使用v3.7.9或更早的发行版。

特点

减少间接调用

所有KIF测试都是用Objective-C编写的。这允许您的代码实现最大程度的集成,同时最小化构建的层。

配置简单

KIF可以直接集成到您的Xcode项目中,因此无需运行额外的Web服务器或安装任何额外的包。

广泛的操作系统和Xcode覆盖

KIF的测试套件正在针对iOS 8+和Xcode 7+运行。较低版本可能仍然可行,但性能可能会有所不同。我们会尽最大努力保留尽可能多的向后兼容性。

像用户一样测试

KIF试图模拟实际用户输入。自动化会在可能的情况下使用触摸事件。

与Xcode测试工具的自动集成

您可以使用Test Navigator轻松运行单个KIF测试,或使用Bots启动夜间验收测试。

看看KIF的实际应用

KIF使用以下描述的技术来验证其内部功能。您可以通过构建和测试KIF方案(使用⌘U)来查看一个测试套件,它测试了其全部功能。查看“KIF Tests”组中的测试,以获得如何构建您自己的测试的想法。

使用CocoaPods安装

CocoaPods是与KIF设置的最简单方法。

首先,您需要为KIF设置一个测试目标。如果您在自动创建单元测试时选择了名为MyApplication_Tests的目标,您可能已经有了。如果您有,并且不打算用它来写单元测试,您可以继续使用它。否则,请按照以下说明创建一个新目标。

在Xcode中选择您的项目,然后点击编辑器左下角的“添加目标”。选择iOS -> 测试 -> iOS 单元测试_bundle。给它一个产品名称,如“验收测试”、“UI测试”或能表明测试过程意图的名称。

测试目标将添加一个头文件和实现文件,可能是与目标名称匹配的“Acceptance_Tests.m/h”。删除这些文件。

一旦您设置了测试目标,请将以下内容添加到您的Podfile文件中。使用您的目标名称作为合适的名称。

target 'Your Apps' do
  ...
end

target 'Acceptance Tests' do
  pod 'KIF', :configurations => ['Debug']
end

在运行pod install完成后,根据下面的最终测试目标配置完成任务,以获取使测试运行的所有最终详细信息。

从GitHub安装

要安装KIF,您需要直接将libKIF静态库链接到您的应用程序中。从kif-framework/KIF下载源代码,并按照以下说明操作。以下截图来自Yosemite上的Xcode 6,但对于任何OS版本上的Xcode 5或更高版本,说明应相同。

我们将使用一个简单的项目作为示例,您可以在本存储库的Documentation/Examples/Testable Swift中找到它。

Simple App

将KIF添加到您的项目文件中

第一步是将KIF项目添加到现有应用程序的./Frameworks/KIF子目录中。如果您的项目使用Git进行版本控制,您可以使用子模块来简化未来的更新。

cd /path/to/MyApplicationSource
mkdir Frameworks
git submodule add https://github.com/kif-framework/KIF.git Frameworks/KIF

如果您不使用Git,只需下载源代码并将其复制到./Frameworks/KIF目录中即可。

将KIF添加到您的工作区

让您的项目了解KIF,请将KIF项目添加到工作空间中,与主项目一起。在Finder中找到KIF.xcodeproj文件,并将其拖拽到项目导航器(⌘1)中。

Added KIF to the project

创建测试目标

您需要为您的应用创建一个测试目标。如果您在创建项目时选择了自动创建单元测试,可能会已经有一个名为MyApplicationTests的测试目标。如果有的话,如果您没有使用它进行单元测试,您可以使用它。否则,按照以下说明创建一个新的。

在Xcode中选择您的项目,然后点击编辑器左下角的“添加目标”。选择iOS -> 测试 -> iOS 单元测试_bundle。给它一个产品名称,如“验收测试”、“UI测试”或能表明测试过程意图的名称。

测试目标将添加一个头文件和实现文件,可能是与目标名称匹配的“Acceptance_Tests.m/h”。删除这些文件。

配置测试目标

现在您有一个测试目标了,将测试添加到该目标中。在项目设置中保留项目导航器选择,并选择项目设置中的新集成测试目标,选择“构建阶段”标签。在“链接二进制与库”部分中,点击“+”按钮。在出现的表格中,选择“libKIF.a”并点击“添加”。重复该过程为CoreGraphics.framework和QuartzCore.framework。

KIF需要IOKit.framework,但它并不位于其他系统框架中。要链接它,将“-framework IOKit”添加到“其他链接器标志”的构建设置中。

Add libKIF library screen shot

Add libKIF library screen shot

KIF利用Objective-C在对象上添加分类的能力,但默认情况下这并不应用于静态库。要启用此功能,将-ObjC标志添加到您的测试包目标的“其他链接器标志”构建设置中,如下所示。

Add category linker flags screen shot

阅读下文的“最终测试目标配置”以获得运行测试的最终细节。

安装可访问性标识符测试

通常情况下,您通过UI元素的访问性标签来识别UI元素,这样KIF可以尽可能真实地模拟用户的交互。然而,在某些情况下,您可能需要使用可访问性标识符,这些标识符不会暴露给用户。如果使用CocoaPods,通过Identifier CocoaPods subspec安装基于标识符的KIF测试。

pod 'KIF/IdentifierTests'

如果不使用 CocoaPods,可以通过包含 "KIFUITestActor-IdentifierTests.h" 来添加基于标识符的 KIF 测试。

最终测试目标配置

您需要确保测试在您的应用程序中运行。在创建新的测试束目标时,Xcode 默认会为您完成此操作,但如果您正在迁移旧束,请按照以下步骤操作。

首先,通过选择 "构建阶段",展开 "目标依赖" 部分,点击 "+" 按钮,然后在出现的新窗口中,选择您的应用程序目标并点击 "添加" 来添加您的应用程序。

接下来,配置您的束加载器。在 "构建设置" 中,展开 "链接" 并将 "Bundle Loader" 编辑为 $(TEST_HOST)。展开 "测试" 部分,并将 "Test Host" 编辑为 $(BUILT_PRODUCTS_DIR)/MyApplication.app/MyApplication(其中 MyApplication 是您的应用程序名称)。另外,请确保 "Wrapper Extension" 设置为 xctest

最后一步是配置您的单元测试,以便在触发测试时(⌘U)运行。点击您的方案名称,选择 "编辑方案..."。在侧边栏中点击 "测试",然后点击左下角的 "+"。选择您的测试目标并点击 "OK"。

示例测试用例

当您的项目配置为使用 KIF 后,是时候开始编写测试了。在 KIF 测试中有两个主要的类:测试用例(KIFTestCase,是 XCTestCase 的子类)和 UI 测试演员(KIFUITestActor)。XCTest 测试运行器加载测试用例类并执行它们的测试。在这些测试内部,测试者执行 UI 操作,通常模拟用户交互。最常用的三个测试者操作是 "点击此视图"、"在此视图中输入文本" 和 "等待此视图"。这些步骤包括在基础 KIF 实现中的 KIFUITestActor 上的工厂方法中。

KIF 依赖于 iOS 内置的无障碍功能来执行其测试步骤。因此,您的应用程序的无障碍功能是至关重要的。这也是确保您的应用程序可供每个人使用的好方法。给您的视图适当标签通常是使应用程序无障碍的一个好起点。更多详细信息可在 Apple 的文档 中找到。

首先步骤是创建一个用于测试某些功能的测试类。在我们的情况下,我们将创建一个登录测试(LoginTests)。创建一个从 KIFTestCase 继承的新类。您可能需要更新导入以指向 <KIF/KIF.h>。测试方法名称提供了一个唯一标识符。您的 KIFTestCase 子类应如下所示

LoginTestCase.h

#import <KIF/KIF.h>

@interface LoginTests : KIFTestCase
@end

登录测试用例.m

#import "LoginTests.h"
#import "KIFUITestActor+EXAdditions.h"

@implementation LoginTests

- (void)beforeEach
{
    [tester navigateToLoginPage];
}

- (void)afterEach
{
    [tester returnToLoggedOutHomeScreen];
}

- (void)testSuccessfulLogin
{
    [tester enterText:@"[email protected]" intoViewWithAccessibilityLabel:@"Login User Name"];
    [tester enterText:@"thisismypassword" intoViewWithAccessibilityLabel:@"Login Password"];
    [tester tapViewWithAccessibilityLabel:@"Log In"];

    // Verify that the login succeeded
    [tester waitForTappableViewWithAccessibilityLabel:@"Welcome"];
}

@end

测试中的大部分测试员操作都已由 KIF 框架定义,但 -navigateToLoginPage-returnToLoggedOutHomeScreen 除外。这些都是自定义操作,这些操作特定于您的应用程序。添加此类步骤很简单,并且是通过 KIFUITestActor 类别的工厂方法完成的,类似于我们添加场景的方式。

KIFUITestActor+EXAdditions.h

#import <KIF/KIF.h>

@interface KIFUITestActor (EXAdditions)

- (void)navigateToLoginPage;
- (void)returnToLoggedOutHomeScreen;

@end

KIFUITestActor+EXAdditions.m

#import "KIFUITestActor+EXAdditions.h"

@implementation KIFUITestActor (EXAdditions)

- (void)navigateToLoginPage
{
    [self tapViewWithAccessibilityLabel:@"Login/Sign Up"];
    [self tapViewWithAccessibilityLabel:@"Skip this ad"];
}

- (void)returnToLoggedOutHomeScreen
{
    [self tapViewWithAccessibilityLabel:@"Logout"];
    [self tapViewWithAccessibilityLabel:@"Logout"]; // Dismiss alert.
}

@end

现在应该已经配置完毕。当您使用测试按钮、⌘U 或 Xcode 测试导航器(⌘5)运行集成测试时。

与其他测试框架一起使用

KIFTestCase 对于运行 KIF 测试不是必需的。测试可以直接在 XCTestCase 或任何子类中运行。基本要求是在您调用 testersystem 时,self 必须是 XCTestCase 的实例,并且您必须在 setUp 中调用 KIFEnableAccessibility

例如,以下 Specta 测试在没有对 KIF 或 Specta 进行任何更改的情况下工作。

#import <Specta.h>
#import <KIF.h>

SpecBegin(App)

describe(@"Tab controller", ^{

  it(@"should show second view when I tap on the second tab", ^{
    [tester tapViewWithAccessibilityLabel:@"Second" traits:UIAccessibilityTraitButton];
    [tester waitForViewWithAccessibilityLabel:@"Second View"];
  });

});

SpecEnd

如果您想使用一个不继承自 XCTestCase 的测试运行器与 KIF 一起使用,您的运行器类只需要实现包含两个必要方法的 KIFTestActorDelegate 协议。

  • (void)failWithException:(NSException *)exception stopTest:(BOOL)stop;
  • (void)failWithExceptions:(NSArray *)exceptions stopTest:(BOOL)stop;

在第一种情况下,测试运行器应记录异常并在 stopYES 时中止测试执行。在第二种情况下,运行器应记录所有异常,并在 stopYES 时中止测试执行。异常利用了 KIF 对 NSException 的扩展,其中包含异常的 userData 中的 lineNumberfilename,以记录错误的来源。

与 Swift 一起使用

由于在单个项目中很容易将 Swift 和 Objective-C 代码结合起来,KIF 完全能够在使用 Objective-C 和 Swift 编写的应用程序中测试。

如果您想使用 Swift 编写测试用例,请注意以下两点。

  1. 您的测试包的桥接头需要 #import <KIF/KIF.h>,因为 KIF 是一个静态库而不是头文件。
  2. testersystem 关键字是 C 预处理器宏,在 Swift 中不可用。您可以通过对 XCTestCase 或任何其他类创建一个小扩展来访问它们。
extension XCTestCase {
    func tester(file : String = #file, _ line : Int = #line) -> KIFUITestActor {
        return KIFUITestActor(inFile: file, atLine: line, delegate: self)
    }

    func system(file : String = #file, _ line : Int = #line) -> KIFSystemTestActor {
        return KIFSystemTestActor(inFile: file, atLine: line, delegate: self)
    }
}

extension KIFTestActor {
    func tester(file : String = #file, _ line : Int = #line) -> KIFUITestActor {
        return KIFUITestActor(inFile: file, atLine: line, delegate: self)
    }

    func system(file : String = #file, _ line : Int = #line) -> KIFSystemTestActor {
        return KIFSystemTestActor(inFile: file, atLine: line, delegate: self)
    }
}

请参阅文档/示例/Testable Swift以获取示例代码。

故障排除

模拟器启动但应用未出现,步骤10秒后超时

当 XCTest 没有有效的测试主机时,会出现此问题。重新阅读关于“包加载器”和“测试主机”设置的说明。你可能漏掉了某些内容。

步骤失败,因为没有找到视图

如果 KIF 无法找到视图,最可能的原因是该视图没有设置其可访问性标签。如果视图定义在 xib 中,则可以使用检查器设置标签。如果是通过编程创建的,只需将 accessibilityLabel 属性设置为所需的标签。

如果标签确实已经正确设置,请仔细查看 KIF 提供的错误信息。这个错误应该会更具体地告诉你视图为什么不可访问。如果你使用 -waitForTappableViewWithAccessibilityLabel:,请确保该视图实际上是可点击的。对于像标签这样的项目,它们不能成为第一个响应者,你可能需要使用 -waitForViewWithAccessibilityLabel: 代替。

首次尝试运行时出现未识别的选择器

如果你首次运行 KIF 时收到以下错误

2011-06-13 13:54:53.295 Testable (Integration Tests)[12385:207] -[NSFileManager createUserDirectory:]: unrecognized selector sent to instance 0x4e02830
2011-06-13 13:54:53.298 Testable (Integration Tests)[12385:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSFileManager createUserDirectory:]: unrecognized selector sent to instance 0x4e02830'

或者如果您在KIF代码中遇到另一个"未识别的选择器"错误,请确保您已如上所述正确设置了-ObjC标志。没有此标志,您的应用程序无法访问KIF正确运行所需的类别方法。

持续集成

推荐使用持续集成(CI)过程,它对于确保您的应用程序始终保持功能非常重要。最简单的方法是使用Xcode,无论是使用机器、Jenkins还是其他使用xcodebuild的工具。对于使用xcodebuild的工具,请查看手册以了解如何使用测试目标。

贡献

我们很高兴你对KIF感兴趣,也很想看看它能带你去哪里。

要向KIF主仓库提交更改,您必须签署个人贡献者许可协议(CLA)。这是一份简短的形式,涵盖了我们的基本要求,并确保你有资格做出贡献。

当您希望在主仓库中看到更改时,请发送拉取请求。在我们合并您的请求之前,我们会确保您在已签署CLA的人名单中。

谢谢,祝您测试愉快!