【问题标题】:Validating configuration files through Unit Tests?通过单元测试验证配置文件?
【发布时间】:2018-05-18 14:11:53
【问题描述】:

我正在构建一个应用程序,用户可以在其中选择config/timezones.php 中定义的时区之一:

return [
    'malta'   => 'Europe/Malta',
    'manila'  => 'Asia/Manila',
    'newyork' => 'America/New_York',
];

此文件有一个数组,其中包含一个标识符和一个有效的时区字符串(如 on PHP.net 所示)

我正在尝试基于测试驱动开发来构建这个应用程序,所以我很自然地编写了一个单元测试来检查用户更改时区时时间是否正确更改:

namespace Tests\Unit;

use Carbon\Carbon;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class TimeZoneTest extends TestCase
{

    use RefreshDatabase;

    /** @test */
    public function the_date_and_time_will_be_displayed_based_on_the_timezone_of_the_user() {

        $user = factory(\App\User::class)->create([
            'timezone' => 'Asia/Manila' // +8 hours
        ]);

        $date = Carbon::create(2018, 1, 1, 0, 0, 0); // 2018-01-01 00:00:00

        $adjustedDate = $date->timezone($user->timezone)->format('Y-m-d H:i:s'); // +8 hours = 2018-01-01 08:00:00

        $this->assertEquals('2018-01-01 08:00:00', $adjustedDate);
    }
}

这很好用,但问题是:如果我在配置文件中打错字,单元测试仍然会通过,但应用程序会中断。

我可以简单地创建另一个单元测试,在其中循环并使用in_array($timezone, timezone_identifiers_list()) 验证我的配置文件中的项目,但我不确定它是否属于单元测试。在我看来,这只需要在提交代码或其他内容时验证一次。

我的问题:我如何/在哪里/何时检查我的配置文件在部署到生产之前是否有效?

【问题讨论】:

  • 尝试在测试中循环遍历它并根据这些值创建一个日期时区对象。如果可行,$x 将是该类的一个实例
  • 配置不应通过单元测试进行测试。所以单元测试仍然有效是一件好事。您不希望更改配置来中断测试运行。损坏/错误的配置将导致错误的输出,虽然测试驱动的开发很好,但不要以 100% 的覆盖率为目标。如果您真的想确保您的应用程序正常工作,您需要添加功能测试。
  • 旁注:$adjustedDate 应该是 User 类或服务的一部分。您正在编写要测试的逻辑,即:$date->timezone($user->timezone)->format('Y-m-d H:i:s'); 在测试用例中。您必须在要使用它的每一段代码中重复该行。将 timezone 设为私有而不是公共属性,并在用户上引入 getFormattedDate() 方法,然后使用时区生成该字符串。

标签: php laravel unit-testing testing


【解决方案1】:

代码与应用程序配置协作,就像它与服务、数据库、系统调用等协作一样。在单元测试中,您应该在与协作者隔离的情况下测试代码,这意味着更改配置不应影响任何单元测试。

因此,要在配置不正确时断言失败,您需要进行集成测试 - 因为集成测试涉及协作者。您将使用的集成测试取决于您在哪里实施了配置健全性检查。

例如,一些项目将配置检查放在前端控制器的最前面,这样如果任何配置是虚假的,就会立即出现异常。如果那是您的配置验证所在,那么您将拥有类似的内容:

/**
 * @expectedException ApplicationException
 * @expectedExceptionCode 500
 */
function test_front_controller_explodes_with_500_error_when_booted_with_bad_configuration() {
    $this->fail('unimplemented');
}

【讨论】:

  • 完全有道理,感谢您的明确回答!
猜你喜欢
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 1970-01-01
相关资源
最近更新 更多