AMYServer 2.1.2

AMYServer 2.1.2

测试已测试
Lang语言 Obj-CObjective C
许可证 Apache 2
发布最后发布2015年11月

Tony MannJustin Martin维护。



 
依赖
GRMustache~> 7.0
KIF~> 3.0
 

AMYServer 2.1.2

  • 作者
  • Brian Nickel

AMYServer KIF 测试演员

AMYServer,代表 AMY Mocks Your Server,提供了一种在 KIF 测试用例内对您的 web 服务器进行模拟的机制。

它与 Mocktail 有何区别? Mocktail 在开发过程中很有用,可以排除服务器这一因素,但它有一些限制,可能会影响测试。

  • 完全忽略请求体。
  • 模拟(主要)限制为一个 URL 对应一个响应,这意味着如果您有一个可能返回完全不同响应体的单一 URL,您在运行测试用例时无法快速切换它们。
  • 没有期望的直接验证。如果您的测试触发网络调用,您必须监视 UI 以查看其反应。

AMYServer 通过创建代表您的服务器的 KIF 测试演员来解决这些问题。通过一点设置,您的测试将发展成一个逻辑故事,您可以真正了解您的系统在做什么。

[tester enterText:@"brian" intoViewWithAccessibilityLabel:@"Username"];
[tester enterText:@"$ecret" intoViewWithAccessibilityLabel:@"Password"];

[myServer waitForLoginWithUsername:@"brian" password:@"$ecret"
          andRespondWithSuccess:YES message:@"Welcome, Brian" token:@"12345"];

[tester waitForViewWithAccessibilityLabel:@"Welcome, Brian"];

AMYServer 还与 Mocktail 集成,简化了设置新测试的过程。如果您有现有的 tail 文件,您可以只需几行代码就将其集成。

查看 AMYServer 实际运行情况

AMYServer 包含一些测试用例以验证其功能。启动测试用例以查看 AMYServer 通过几个标准情况。

安装

可以使用CocoaPods安装 AMYServer。

target 'Acceptance Tests' do
  pod 'AMYServer', '~> 2.0'
end

示例 1:使用 Mocktails

此示例假设您已经熟悉 KIF 2.0 和 Mocktail。

第一步是定义您的服务器及其使用的 API。

ExampleServer.h

#import "AMYServer.h"

#define exampleServer KIFActorWithClass(ExampleServer) // (3)

@interface ExampleServer : AMYServer // (1)

- (void)waitForLoginAndRespondWithMessage:(NSString *)message
                                    token:(NSString *)token; // (2)

@end
  1. 为您的服务器创建一个 AMYServer 实例。
  2. 定义在脚本上下文中有意义的方法,包括您可供验证或提供的信息。
  3. 定义您将使用的演员快捷方式,类似于 tester

ExampleServer.m

#import "ExampleServer.h"

@implementation ExampleServer

- (NSURL *)baseURL
{
    return [NSURL URLWithString:@"https://example.com/services/"]; // (1)
}


- (void)waitForLoginAndRespondWithMessage:(NSString *)message
                                    token:(NSString *)token
{
    [self waitForRequestMatchingMocktail:@"successful-login"
          andRespondWithValues:@{@"token": token ?: @"", @"message": message ?: @""}]; // (2)
}

@end
  1. 定义服务器将响应的基础 URL。
  2. 选择要用于响应的模拟以及要使用的值。

successful-login.tail

POST
login.json
200
application/json

{
    "success": true,
    "message": "{{{message}}}",
    "token": "{{{token}}}"
}

定义您的 Mocktail 并将其包含在测试目标中。

配置完成后,您可以编写一个使用它的测试用例。

LoginTests.m

#import <KIFTestCase.h>
#import "ExampleServer.h"

@interface AMYServerTests : KIFTestCase
@end

@implementation AMYServerTests

- (void)beforeAll
{
    [exampleServer start]; // (1)
}

- (void)afterAll
{
    [exampleServer stop]; // (5)
}

- (void)testSuccessfulLogin
{
    [tester tapViewWithAccessibilityLabel:@"Log In"]; // (2)
    [exampleServer waitForLoginAndRespondWithMessage:@"Welcome, Brian" token:@"12345"]; // (3)
    [tester waitForViewWithAccessibilityLabel:@"Welcome, Brian"]; // (4)
}

@end
  1. 开始模拟。
  2. 触发一个请求。
  3. 等待并响应请求。
  4. 监视响应的效果。
  5. 停止模拟。

示例 2:高级鸡尾酒

AMYServer提供了一些基于鸡尾酒的功能。

  1. 在测试步骤中执行请求体验证。
  2. 使用 Mustache 模板进行完全自定义。
  3. 使用 Mustache 替换响应头。

利用这些功能,我们可以增强登录测试步骤,以验证用户名和密码,并在响应中注入自定义头。

ExampleServer.m

- (void)waitForLoginWithUsername:(NSString *)username
                        password:(NSString *)password
           andRespondWithMessage:(NSString *)message
                           token:(NSString *)token
{
    [self waitForRequestMatchingMocktail:@"successful-login"
          withHTTPBodyMatchingBlock:^KIFTestStepResult(NSData *body, NSError *__autoreleasing *error) {

              id json = [NSJSONSerialization JSONObjectWithData:body options:0 error:NULL];
              KIFTestWaitCondition([json[@"username"] isEqualToString:username], error, @"Could not find username");
              KIFTestWaitCondition([json[@"password"] isEqualToString:password], error, @"Could not find password");
              return KIFTestStepResultSuccess;
          }
          andRespondWithValues:@{@"token": token ?: @"", @"message": message ?: @""}];
}

@end

在这种情况下,AMYServer将忽略不具有正确用户名和密码的请求,并提供一个有意义的结果。

successful-login.tail

POST
login.json
200
application/json
X-Application-Token: {{{token}}}

{
    "success": true,
    "message": "{{{message}}}",
    "token": "{{{token}}}"
}

在这里,AMYServer注入了一个包含令牌的自定义头。

示例 3:默认 Mustache 值

与其每次渲染模板时都提供所有值,AMYServer 允许您提供一个带有默认值的 JSON 文件。该文件的名称与尾部文件相同,但有一个额外的扩展名 .defaults.json

successful-login.tail.defaults.json

{ "message": "Good morning, sir", "token": "1234" }

示例 4:自定义行为

AMYServer不仅限于鸡尾酒。它可以用来按每次 1000 字节、每 5 秒发送一个字节的方式服务图片。

- (void)waitForImageRequestAndRespondPainfully
{
    AMYRequest *request = [self waitForRequestMatchingBlock:^KIFTestStepResult(NSURLRequest *request, NSError **error) {
        KIFTestWaitCondition([request.URL.lastPathComponent isEqualToString:@"image.do"], error, @"Could not find request for image.do");
        return KIFTestStepResultSuccess;
    }];

    [request respondWithSatusCode:200 headerFields:@{@"Content-Size": @"1000000"}];
    while (!done) {
        [request sendData:moreData];
        [self waitForTimeInterval:5];
    }
    [request close];
}

首先我们等待匹配我们想要规则的请求。在这种情况下,最后一个路径组件应该是 "image.do"。然后我们发送响应头,并缓慢构建正文,最后关闭。这里重要的是,我们可以在数据返回的同时执行任何我们想要的操作。