代表“保持功能性”的 KIF(Keep It Functional),是一个 iOS 集成测试框架。它通过利用操作系统为有视觉障碍的用户提供的可访问性属性,使 iOS 应用易于自动化。
KIF-next 是 KIF 的一个分支,使用标准的 ocunit
测试目标构建和执行测试。测试是同步进行的(运行运行循环以强制时间流逝),而不是通过构建一系列步骤来进行的,这允许进行更复杂的逻辑和组合。这也使 KIF-next 能够利用 Xcode 5 测试导航器、命令行构建工具和测试报告程序。了解有关 Xcode 5 特性的更多信息。
KIF 使用未记录的 Apple API。 这大多数 iOS 测试框架都是这样,对于测试目的来说这是安全的,但重要的是 KIF 不能出现在生产代码中,因为它会导致您的应用程序提交被苹果公司拒绝。按照以下说明确保为您的项目正确配置 KIF。
还有一个使用 KIF 进行 Mac OS X 应用程序集成的移植正在进行中。
KIF 的所有测试都是用 Objective C 编写的。这允许最大程度地与您的代码集成,同时最小化您需要构建的层。
KIF 直接集成到您的 iOS 应用中,因此不需要运行额外的网页服务器或安装任何额外的包。
KIF 尽可能地模仿实际的用户输入。自动化尽可能使用触摸事件。
Xcode 5 引入了一套新的测试和持续集成工具,这些工具建立在与KIF-next相同的测试平台上。您可以使用测试导航器轻松运行单个KIF测试,或使用Bots启动夜间的验收测试。
KIF-next使用以下描述的技术来验证其内部功能。您可以通过简单地构建和测试KIF方案来查看一个涵盖了其全部功能的测试套件(通过按下⌘U)。查看“KIF测试”组中的测试以获取构建您自己的测试的想法。
要安装KIF,您需要将libKIF静态库直接链接到您的应用程序中。从bnickel/KIF/tree/kif-next下载源代码并遵循以下说明。
**注意**:以下说明假定您使用的是Xcode 4或更高版本。对于Xcode 3,您将无法利用工作区,因此说明将略有不同。
第一步是将KIF项目添加到现有应用程序的./Frameworks/KIF子目录中。如果您的项目使用Git进行版本控制,您可以使用子模块使未来的更新更容易。
cd /path/to/MyApplicationSource
mkdir Frameworks
git submodule add -b KIF-next https://github.com/square/KIF.git Frameworks/KIF
如果您不使用Git,只需下载源代码并将其复制到./Frameworks/KIF目录中。
通过将KIF项目与主项目一起添加到工作区来让您的项目了解KIF。在Finder中找到KIF.xcodeproj文件,将其拖动到项目导航器(⌘1)。如果您还没有工作区,Xcode会询问您是否想创建一个新的工作区。在创建后点击“保存”。
您需要为您的应用程序创建一个测试目标。如果您选择自动创建单元测试,可能已经有一个名为“MyApplication”_Tests的目标。如果您已经有一个目标,且不使用它进行单元测试,则可以继续使用它。否则,按照以下说明创建一个新的目标。
在Xcode中选中项目,点击编辑器左下角的“添加目标”。选择iOS -> 其他 -> Cocoa Touch Unit Testing Bundle。为其提供一个产品名称,如“验收测试”、“UI测试”或表示您的测试过程意图的名称。即使您的应用程序其他部分不使用它,您也可以选择“使用自动引用计数”,这将使您的生活更加容易。
测试目标将添加一个头文件和实现文件,可能是一个名为“Acceptance_Tests.m/h”的文件,与您的目标名匹配。将其删除。
现在您已有一个测试目标,请将测试添加到该目标中。在项目导航器中仍然选择项目设置,选择新的集成测试目标,并在项目设置中选择“构建阶段”标签。在“链接二进制与库”部分,点击“+”按钮。在出现的表单中,选择“libKIF.a”并点击“添加”。重复此过程为CoreGraphics.framework。
KIF利用Objective C在对象上添加分类的能力,但默认情况下不会为静态库启用此功能。要启用此功能,请在“其他链接器标志”构建设置中添加-showr的标志,如下所示。
有关让您的测试运行到最后配置的详细说明,请参阅下面的“最终测试目标配置”。
您需要使测试运行在您的应用中。为此,首先通过选择“构建阶段”、展开“目标依赖”部分、点击"+"按钮、在新的表格中选择您的应用目标并点击“添加”来添加您的应用。
接下来,配置您的捆绑加载器。在“构建设置”中,展开“链接”并编辑“捆绑加载器”为$(BUILT_PRODUCTS_DIR)/My App.app/My App
(其中 My App 是您的应用名称)。展开“单元测试”部分并编辑“测试主机”为$(BUNDLE_LOADER)
。
最后一步是配置您的单元测试以便在您触发测试时(⌘U)运行。点击您的方案名称,然后选择“编辑方案...”。在侧边栏中点击“测试”,然后点击左下角的"+"。选择您的测试目标并点击“确定”。
您的项目配置为使用KIF之后,就可以开始编写测试了。KIF测试中使用了两个主要的类:测试用例(KIFTestCase
,SenTestCase
的子类)和UI测试演员(KIFUITestActor
)。ocunit测试运行器加载测试用例类并执行它们的测试。在这些测试中,测试者执行UI操作,这些操作通常模拟用户交互。最常见的三个测试者操作是“点击此视图”、“在此视图中输入文本”和“等待此视图”。这些步骤包含在基KIF实现的KIFUITestActor
的基本工厂方法中。
KIF依赖于iOS内置的访问性来执行其测试步骤。因此,确保您的应用完全具有可访问性非常重要。这也可以确保您的应用对视力受损者友好。使应用程序具有可访问性通常只需为视图提供合理的标签。更多详细信息请参阅Apple的文档。
第一步是创建一个测试类以测试某些功能。在我们的例子中,我们将创建一个登录测试(LoginTests
)。创建一个新的类,继承自KIFTestCase。您可能需要更新导入以指向<KIF/KIF.h>
。测试方法名称提供了一个唯一标识符。您的KIFTestCase子类看起来可能像这样
LoginTestCase.h
#import <KIF/KIF.h>
@interface LoginTests : KIFTestCase
@end
LoginTestCase.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测试导航器(⌘5)运行集成测试时。
KIFTestCase
对于运行KIF测试不是必需的。测试可以直接在SenTestCase
或任何子类中运行。基本要求是当您调用tester
或system
时,self
必须是SenTestCase
的一个实例。
例如,以下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
如果您想使用不子类化SenTestCase
的测试运行器运行KIF,您的运行器类只需要实现包含两个必需方法的KIFTestActorDelegate
协议。
在第一种情况下,测试运行器应该记录异常并在stop
为YES
时停止测试执行。在第二种情况下,运行器应记录所有异常,并在stop
为YES
时停止测试执行。异常利用OCUnit对NSException
的扩展,具有lineNumber
和filename
属性,用于记录错误的起源。
当ocunit没有有效的测试主机时,会出现此问题。发生这种情况时,ocunit将在无应用的情况下以逻辑模式运行您的测试,这会导致UI测试失败。
再次阅读关于“包加载器”和“测试主机”设置的说明。您可能遗漏了某些内容。
如果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代码中遇到其他“未识别的选择器”错误,请确保您已正确设置如上所述的-ObjCflag。没有这个标志,您的应用无法访问KIF正常运行所必需的类别方法。
非常推荐您使用持续集成(CI)流程,这对确保您的应用始终可用非常有用。最容易的方法是使用Xcode 5,无论是使用Bots,还是Jenkins或其他使用xcodebuild的工具。对于使用xcodebuild的工具,请查看使用测试目的地的说明手册页面。
我们很高兴您对KIF感兴趣,并期待看到您如何将其发扬光大。
对master KIF仓库做出贡献的人必须签署个人贡献者许可协议(CLA)。这是一份简短的表格,覆盖了所有方面并确保您有资格贡献力量。
当您想在上层仓库看到更改时,请发送一个拉取请求。在我们合并您的请求之前,我们会确保您在签署过CLA的人员名单中。
谢谢,祝测试愉快!