【问题标题】:How to use Codeception to test laravel 5 APIs?如何使用 Codeception 测试 laravel 5 API?
【发布时间】:2015-11-02 10:11:07
【问题描述】:

我是 Codeception 的新手,我正在尝试测试我使用 Laravel 5 构建的 Web 服务。我正在遵循指南 here

所以我先创建了一个叫 api 的套件:

codecept generate:suite api

api.suite.yml

class_name: ApiTester
modules:
    enabled:
        - REST:
            url: http://localhost:8000/api/
            depends: Laravel5

AuthenticateUserCept.php

<?php 
$I = new ApiTester($scenario);
$I->wantTo('authenticate a user');
$I->haveHttpHeader('Content-Type', 'application/x-www-form-urlencoded');
$I->sendPOST('/authenticate', [
    'username' => 'archive',
    'email' => 'admin@admin.com',
    'password' => 'password'
]);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();

我已经使用 Postman 尝试过,它运行良好。 /authenticate 路由采用 3 个参数并愉快地吐出 JWT 令牌,但我无法使其与 Codeception 一起使用。

1) Failed to authenticate a user in AuthenticateUserCept (tests/api//AuthenticateUserCept.php)

 Step  I see response code is 200
 Fail  Failed asserting that 500 matches expected 200.

Scenario Steps:

 3. $I->seeResponseCodeIs(200)
 2. $I->sendPOST("/authenticate",{"username":"archive","email":"admin@admin.com","password":"password"})
 1. $I->haveHttpHeader("Content-Type","application/x-www-form-urlencoded")

我哪里错了?此外,我仍然不清楚如何重构这个特定的测试,以便为我提出的其他请求提供 JWT。任何帮助表示赞赏。

编辑 api.suite.yml 中的更改

class_name: ApiTester
modules:
    enabled:
        - REST:
            url: http://localhost:8000/api/
            depends: Laravel5
    config: 
        Laravel5:
            environment_file: .env.testing

【问题讨论】:

    标签: php laravel laravel-5 codeception


    【解决方案1】:

    在我回答之前,一些cmets:

    • 在 api.suite.yml 的已启用行上,我包括:已启用:[PhpBrowser, REST, ApiHelper, Asserts]。
    • REST 行中的 url 对 API 套件没有任何影响,它通常只用于验收套件。这应该是通过路由直接进入您的代码,而不是在进行 HTTP 调用时使用 phpbrowser 模式或类似模式。
    • 您可以使用 Laravel5 模式,而不是使用 PhpBrowser 模式 -- 前者将通过中间件发送请求,如果 APP_ENV 设置为测试,Laravel5 模式将不会通过中间件发送请求。

    关于如何解决这个问题,我会首先尝试弄清楚代码在做什么以吐出 500 错误。您可能会做的一件事是尝试在代码中插入一些调试/日志行。另一件事是在测试用例中放入这样的一行:

    $I->seeResponseContains('blablabla');

    当然会失败,但它会在 tests/_output 目录中产生一个输出,这样您就可以准确地看到代码返回的响应以及 500 错误(当然您需要在测试之前执行此步骤对于 200 条件,否则您的测试将在该步骤退出)。

    测试用例中此类错误的一个常见原因是验证应用于传递给控制器​​方法的自定义请求类。如果该验证失败,则控制器方法不会受到影响,并且您将收到 500 错误,而无法在控制器中对其进行调试。我认为这种类型的自定义请求类是一个坏主意。

    另一个可能的调查路线是构建一个功能测试来测试相同的路线。通过 Laravel5 辅助模块进行的功能测试通常更容易开始工作和调试。一旦您进行了基本的功能测试并解决了您遇到的任何问题,那么 API 测试就更容易工作了。

    【讨论】:

    • 感谢您的精彩见解。所以我继续,这次将 POST 请求更改为/api/authenticate。所以我深入研究了测试的输出。而且我发现了一个中间件,它检查令牌以评估有效负载正在搞砸这件事,但出于显而易见的原因,该中间件不应该对/api/authenticate 采取行动。但是当我从内核评论中间件时,它运行良好。我该如何解决这个问题?
    • 把这个放到你的 api.suite.yml: config: Laravel5: environment_file: .env.testing 在你的文件 .env.testing 中,确保你已经设置了: APP_ENV=testing 否则应该是与您的 .env 文件相同。默认情况下,当 APP_ENV=testing 中间件不运行时。您可以根据具体情况重新启用它,但这应该可以解决您的问题。
    • 我不确定我是否掌握了全部内容。我更改了配置文件,我什至会编辑我的答案以包含更改。我创建了 .env.testing 并将 APP_ENV 设置为测试。但我不明白你对中间件的意思。测试仍然失败。尝试解析不应解析的令牌的中间件。一旦我在内核中评论中间件,它就通过了,但这不是我希望解决这个问题的方式。中间件查看请求是否为api/authenticate,然后跳过。也许codeception没有执行HTTP请求?它在另一个中做到了。我很困惑。
    • 我在 REST 依赖项中将 Laravel5 更改为 PhpBrowser。 Laravel5 模块没有模拟真实的 HTTP 请求,这就是中间件运行不正确的原因。 PhpBrowser 显然模拟了真实的 HTTP 请求。请也使用此信息更新答案,我会接受。不过,谢谢您提供其他信息。 :)
    • 好的,请注意——在某些情况下,如果您不希望默认启用中间件,则 Laravel5 模块更可取。您始终可以专门为任何给定测试启用或禁用中间件。
    猜你喜欢
    • 2016-02-09
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 2019-03-27
    相关资源
    最近更新 更多