测试已测试 | ✓ |
Lang语言 | Obj-CObjective C |
许可证 | MIT |
发布最后发布 | 2015年11月 |
由Paul Evans维护。
依赖项 | |
PEObjc-Commons | ~> 1.0.86 |
PEWire-Control | ~> 1.0.5 |
PESimu-Select 是一个 iOS 静态库,提供了一个用于选择我们所说的 "模拟" 的视图控制器,目的是为了欺骗 Cocoa 的 URL 加载系统,从而返回控制的模拟 HTTP 响应给 Web 服务调用。
PESimu-Select 基于 PEWire-Control 工作。
PESimu-Select 也是 PE* iOS 库套件 的一部分。
目录表
想象您正在构建一个 iPhone 应用程序,该应用程序提供了一个屏幕,允许用户登录或创建账户。对于这两个用例,应用程序可能都需要向您的服务器发起一个 Web 服务调用。现在,让我们假设,在您开发这些屏幕的时候,Web 服务还没有(它们由服务器开发人员并行于应用程序开发)。您该如何做?您有几个选择;有些比其他的选择更复杂。最简单的方法就是简单地不发起任何 Web 服务调用,并且让您的应用程序硬编码以允许您进入下一个屏幕。
问题是,您希望能够开发和测试应用程序的 "全栈"。也就是说,您希望能够开发和测试真正发起 Web 服务调用的代码、序列化和反序列化请求和响应、适当处理失败模式等。Enter PESimu-Select。
使用 PESimu-Select,您只需创建一些代表与您的应用程序相关联的各种用例的 HTTP 响应的 XML 文件。PESimu-Select 提供了一个视图控制器,您可以将它整合到您应用程序的开发构建中,以便测试各种 Web 服务响应场景。这样,您可以开发和测试应用程序的全栈,并在隔离的情况下进行测试。
顺便提一下,PESimu-Select的设计是这样的,它认为应用中的每个屏幕都可能涉及多个使用案例。例如,在我们的“登录或创建账户”屏幕中,实际上有两个使用案例:1)登录和2)创建账户。
在这个阶段,我们的文件夹结构如下
application-screens/
unauthenticated-landing-screen/
在“unauthenticated-landing-screen/”文件夹下,为该屏幕上的每个使用案例创建一个文件夹。在我们的例子中,这些使用案例是:登录和创建账户。名称不重要,选择简洁明了的名字。现在我们的文件夹结构应该如下所示
application-screens/
unauthenticated-landing-screen/
create-account/
login/
现在我们准备创建实际的XML HTTP响应文件。关于这些文件的特定语法,请参阅PEWire-Control的文档。思想是,对于您想测试的每个场景,创建一个捕获该场景的XML HTTP响应。例如,对于登录使用案例,服务器团队的Web服务设计可能规定,对于错误的登录尝试,返回HTTP状态码401,并在响应体中以某种形式包含一些消息,格式化为JSON。对于成功的登录,响应可能是200,在体中包含用户配置文件信息并在cookie中包含一个认证令牌。对于您想要考虑的每个可能场景,在该使用案例的文件夹中创建一个XML HTTP响应文件。完成这些操作后,您的文件夹结构可能如下所示
application-screens/
unauthenticated-landing-screen/
create-account/
fail-user-already-registered.xml
success-test-user-0.xml
login/
fail-server-failure.xml
fail-unknown-username.xml
success-test-user-0.xml
success-test-user-1.xml
如您所见,我们可以为广泛的场景创建模拟HTTP响应XML文件,包括服务器错误(响应状态码为500)和客户端错误(4XX响应代码)。
最后,您需要将根文件夹“application-screens/”添加到您的Xcode项目中。通常您希望将此文件夹挂在应用的支持文件“Supporting Files”文件夹下。
在您应用的全局代理(delegate).h文件中,添加以下导入语句
#import <PESimu-Select/SSELUtils.h>
声明为属性
@property (nonatomic) SSELUtils *sselutils;
然后,在您的应用:didFinishLaunchingWithOptions:方法中,实例化您的_sselutils实例,提供您的顶级屏幕文件夹的名称
_sselutils = [SSELUtils utilsWithBaseResourceFolder:@"application-screens"];
因为每个视图控制器都需要对我们的_sselutils实例进行访问,而且您可能不希望将实例作为初始化参数传递给每个视图控制器的初始化器(毕竟,我们的_sselutils实例只是开发工具),在您的AppDelegate.h文件中定义一个宏,如下所示(参照此SO答案http://stackoverflow.com/a/4141202/1034895)
#define AppDelegate (YourAppDelegate *)[[UIApplication sharedApplication] delegate]
现在,您的每个视图控制器可以简单地:[YourAppDelegate sselutils]
来获取对它的访问。
在您视图控制器的viewDidLoad
方法中,添加以下行(在这个例子中,假设这是我们“UnauthenticatedLandingScreen” UIViewController的子类)
[[YourAppDelegate sselutils] addSimulationTogglerForScreen:@"unauthenticated-landing-screen"
ontoViewController:self];
请注意,我们指定了与该视图控制器对应的“screen”文件夹的名称。《addSimulationTogglerForScreen:ontoViewController:》将为视图控制器的视图顶部右侧添加一个按钮,点击时会弹出PESimu-Select的模拟选择屏幕。顺便提一下,PESimu-Select附带一个实现这些步骤的演示应用。以下是流程的图像
顺便提一下,对于这个演示应用,为了简洁,我只为“创建账户”使用案例定义了2个模拟HTTP XML文件,并为“登录”使用案例定义了2个。以下是Xcode中文件夹结构的样子
请注意,“Use Case Simulations”屏幕正是由我们的文件夹结构驱动的
顺便提一下,表格视图部分标题是由使用案例文件夹名称驱动的。表格视图的标题和副标题是由对应XML文件的/http-response/annotation/@name
和/http-response/annotation
值驱动的。
在此处,您可以触摸以选择每个用例的模拟,并可选择执行请求数据和响应时延(以秒为单位)。
触摸“完成”以启用模拟(这与使用PEWire-Control相同 —— 它使用OHHTTPStubs来篡改Cocoa的URL加载系统以相应地返回那些HTTP响应)。要清除模拟并返回正常状态,请触摸“清除模拟”按钮。
如果您不希望在视图控制器顶部出现蓝色“切换模拟”按钮,可以使用摇晃手势来调出模拟选择屏幕。为了实现这一点,在您的应用程序代理中导入SSELUIWindow
#import <PESimu-Select/SSELUIWindow.h>
并在application:didFinishLaunchingWithOptions中实例化self.window时将UIWindow
替换为SSELUIWindow
self.window = [[SSELUIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
然后,在您的视图控制器中,使用
[[YourAppDelegate sselutils] reactToShakeGestureForScreen:@"unauthenticated-landing-screen"
ontoViewController:self];
所有这些步骤都可以在演示应用程序中找到。
(每个库都作为CocoaPods启用的iOS静态库实现。)