2020-10-24 16:32:45
【現在時刻を含む処理のテスト】テスト容易な「午前1時59分59秒までは前日として扱う」コードとテストコード【PHP】
【ユニットテスト】テスト容易な「午前1時59分59秒までは前日として扱う」コードとテストコード【PHP】
時刻を含むテスト容易なコードってどんな感じなんでしょうね。自分なりのテスト容易なコードを書いてみました。
時刻を含むテスト容易なコードの書き方の定石ってあるのでしょうかね。
目次
- 【ユニットテスト】テスト容易な「午前1時59分59秒までは前日として扱う」コードとテストコード【PHP】
- 目次
- 環境
- composer.jsonの内容
- ディレクトリ構成
- 準備
- 仕様
- ユニットテスト容易なシステム上の日付を取得するコード
- テストコード
- PHPUnit実行
- 終わり
環境
- windows10 pro 64bit
- PHP Version 7.4.9
- Composer version 1.8.0
- PHPUnit Version 9.4.2
composer.jsonの内容
{
"name": "nao000dotcom/testsdatetime",
"require": {},
"autoload": {
"classmap": [
"src/"
]
},
"require-dev": {
"phpunit/phpunit": "^9"
}
}
ディレクトリ構成
testsdatetime
├─src
│ │─classes
│ │ └─Sample.php # 時刻を扱うコード
│ └─tests
│ └─SampleTest.php # テストコード
│─vendor
│─composer.json
└─composer.lock
準備
composer install
して、composer dump-autoload
します。今更ですが、autoload ってすごくないですか。
composer install
を実行しますcomposer dump-autoload
を実行します
仕様
- 午前1時59分59秒までは前日として扱う
- 午前2時00分00秒からはその日付として扱う
- 例1: 2020年10月24日 01時59分59秒 は、システム上では前日の 2020年10月23日 として扱う
- 例2: 2020年10月24日 02時00分00秒 は、システム上では前日の 2020年10月24日 として扱う
- ミリ秒以下は考慮しません
- 秒数までを考慮します
ユニットテスト容易なシステム上の日付を取得するコード
メソッドの引数に日付を文字列で形式 Y-m-d H:i:s
で設定するメソッドを用意します。形式 Y-m-d H:i:s
を保証する処理は用意しておりません。
<?php
class Sample
{
/**
* 午前1時59分59秒までは前日として扱う
* 午前2時00分00秒からはその日付として扱う
*/
public function get_treat_as_execute_date($datetime_str = '') :string {
$dt = new Datetime($datetime_str);
$end_datetime_str = $dt->format('Y-m-d 01:59:59');
$end_dt = new Datetime($end_datetime_str);
if ($dt <= $end_dt) {
return $dt->modify('-1 day')->format('Y-m-d');
}
return $dt->format('Y-m-d');
}
}
テストコード
月跨ぎ・年跨ぎ・うるう年・非うるう年、を考慮したテストコードを書いていますが、どのくらいテストするべきなのかよく分かっていません。
<?php
use PHPUnitFrameworkTestCase;
final class SampleTest extends TestCase
{
public function test_2020年10月24日01時59分59秒は2020年10月23日として扱う()
{
$sample = new Sample();
$actuall = $sample->get_treat_as_execute_date('2020-10-24 01:59:59');
$expect = '2020-10-23';
$this->assertEquals($expect, $actuall);
}
public function test_2020年10月24日02時00分00秒は2020年10月24日として扱う()
{
$sample = new Sample();
$actuall = $sample->get_treat_as_execute_date('2020-10-24 02:00:00');
$expect = '2020-10-24';
$this->assertEquals($expect, $actuall);
}
public function test_月を跨ぐとき_2020年11月01日01時59分59秒は2020年10月31日として扱う()
{
$sample = new Sample();
$actuall = $sample->get_treat_as_execute_date('2020-11-01 01:59:59');
$expect = '2020-10-31';
$this->assertEquals($expect, $actuall);
}
public function test_月を跨ぐとき_2020年11月01日02時00分00秒は2020年11月01日として扱う()
{
$sample = new Sample();
$actuall = $sample->get_treat_as_execute_date('2020-11-01 02:00:00');
$expect = '2020-11-01';
$this->assertEquals($expect, $actuall);
}
public function test_年末年始_2021年01月01日01時59分59秒は2020年12月31日として扱う()
{
$sample = new Sample();
$actuall = $sample->get_treat_as_execute_date('2021-01-01 01:59:59');
$expect = '2020-12-31';
$this->assertEquals($expect, $actuall);
}
public function test_年末年始_2020年01月01日02時00分00秒は2020年01月01日として扱う()
{
$sample = new Sample();
$actuall = $sample->get_treat_as_execute_date('2021-01-01 02:00:00');
$expect = '2021-01-01';
$this->assertEquals($expect, $actuall);
}
public function test_うるう年の2月_2020年03月01日01時59分59秒は2020年02月29日として扱う()
{
$sample = new Sample();
$actuall = $sample->get_treat_as_execute_date('2020-03-01 01:59:59');
$expect = '2020-02-29';
$this->assertEquals($expect, $actuall);
}
public function test_非うるう年の2月_2021年03月01日01時59分59秒は2021年02月28日として扱う()
{
$sample = new Sample();
$actuall = $sample->get_treat_as_execute_date('2021-03-01 01:59:59');
$expect = '2021-02-28';
$this->assertEquals($expect, $actuall);
}
}
PHPUnit実行
失敗するコードを書いていないので成功しかしてないです。
PS C:xampphtdocsstudy estsdatetime> ./vendor/bin/phpunit tests
PHPUnit 9.4.2 by Sebastian Bergmann and contributors.
........ 8 / 8 (100%)
Time: 00:00.015, Memory: 4.00 MB
OK (8 tests, 8 assertions)
PS C:xampphtdocsstudy estsdatetime>
終わり
以上です。