アサーション
アサーションは、実際の値が期待値に対応することを確認するために使用されます。これらは
Tester\Assert
クラスのメソッドです。
最も適切なアサーションを選択してください。Assert::same($a, $b)
は
Assert::true($a === $b)
よりも優れています。なぜなら、失敗した場合に意味のあるエラーメッセージが表示されるからです。2
番目のケースでは、false should be true
のみが表示され、変数 $a
と $b
の内容については何もわかりません。
ほとんどのアサーションには、オプションの $description
パラメータを含めることもできます。これは、期待が失敗した場合にエラーメッセージに表示されます。
例では、エイリアスが作成されていることを前提としています。
use Tester\Assert;
Assert::same ($expected, $actual, ?string $description=null)
$expected
は $actual
と同一でなければなりません。PHP 演算子
===
と同じです。
Assert::notSame ($expected, $actual, ?string $description=null)
Assert::same()
の逆。つまり、PHP 演算子 !==
と同じです。
Assert::equal ($expected, $actual, ?string $description=null, bool $matchOrder=false, bool $matchIdentity=false)
$expected
は $actual
と同じでなければなりません。Assert::same()
とは異なり、オブジェクトの同一性、配列内のキー ⇒ 値ペアの順序、およびわずかに異なる 10
進数は無視されます。これは $matchIdentity
と $matchOrder
を設定することで変更できます。
次のケースは equal()
の観点からは同じですが、same()
の観点からは同じではありません。
Assert::equal(0.3, 0.1 + 0.2);
Assert::equal($obj, clone $obj);
Assert::equal(
['first' => 11, 'second' => 22],
['second' => 22, 'first' => 11],
);
ただし、注意してください。配列 [1, 2]
と [2, 1]
は同じではありません。なぜなら、キー ⇒
値ペアではなく、値の順序のみが異なるからです。配列 [1, 2]
は
[0 => 1, 1 => 2]
と書くこともでき、したがって [1 => 2, 0 => 1]
が同じと見なされます。
さらに、$expected
でいわゆる očekávání を使用できます。
Assert::notEqual ($expected, $actual, ?string $description=null)
Assert::equal()
の逆。
Assert::contains ($needle, string|array $actual, ?string $description=null)
$actual
が文字列の場合、部分文字列 $needle
を含まなければなりません。配列の場合、要素 $needle
を含まなければなりません(厳密に比較されます)。
Assert::notContains ($needle, string|array $actual, ?string $description=null)
Assert::contains()
の逆。
Assert::hasKey (string|int $needle, array $actual, ?string $description=null)
$actual
は配列でなければならず、キー $needle
を含まなければなりません。
Assert::notHasKey (string|int $needle, array $actual, ?string $description=null)
$actual
は配列でなければならず、キー $needle
を含んではいけません。
Assert::true ($value, ?string $description=null)
$value
は true
でなければなりません。つまり、$value === true
です。
Assert::truthy ($value, ?string $description=null)
$value
は真でなければなりません。つまり、条件 if ($value) ...
を満たします。
Assert::false ($value, ?string $description=null)
$value
は false
でなければなりません。つまり、$value === false
です。
Assert::falsey ($value, ?string $description=null)
$value
は偽でなければなりません。つまり、条件 if (!$value) ...
を満たします。
Assert::null ($value, ?string $description=null)
$value
は null
でなければなりません。つまり、$value === null
です。
Assert::notNull ($value, ?string $description=null)
$value
は null
であってはなりません。つまり、$value !== null
です。
Assert::nan ($value, ?string $description=null)
$value
は Not a Number でなければなりません。NAN 値のテストには、Assert::nan()
のみを使用してください。NAN 値は非常に特殊であり、アサーション Assert::same()
または
Assert::equal()
は予期せず動作する可能性があります。
Assert::count ($count, Countable|array $value, ?string $description=null)
$value
内の要素の数は $count
でなければなりません。つまり、count($value) === $count
と同じです。
Assert::type (string|object $type, $value, ?string $description=null)
$value
は指定された型でなければなりません。$type
として文字列を使用できます。
array
list
– ゼロから始まる昇順の数値キーでインデックス付けされた配列bool
callable
float
int
null
object
resource
scalar
string
- クラス名または直接オブジェクト。その場合、
$value instanceof $type
でなければなりません。
Assert::exception (callable $callable, string $class, ?string $message=null, $code=null)
$callable
を呼び出すと、クラス $class
の例外がスローされなければなりません。$message
を指定した場合、例外メッセージも パターンに一致 しなければならず、$code
を指定した場合、コードも厳密に一致しなければなりません。
次のテストは、例外メッセージが一致しないため失敗します。
Assert::exception(
fn() => throw new App\InvalidValueException('Zero value'),
App\InvalidValueException::class,
'Value is to low',
);
Assert::exception()
はスローされた例外を返します。したがって、ネストされた例外もテストできます。
$e = Assert::exception(
fn() => throw new MyException('Something is wrong', 0, new RuntimeException),
MyException::class,
'Something is wrong',
);
Assert::type(RuntimeException::class, $e->getPrevious());
Assert::error (string $callable, int|string|array $type, ?string $message=null)
関数 $callable
が期待されるエラー(つまり、警告、通知など)を生成したことを確認します。$type
として、E_...
定数の 1 つ、たとえば E_WARNING
を指定します。そして、$message
を指定した場合、エラーメッセージも パターンに一致 しなければなりません。例:
Assert::error(
fn() => $i++,
E_NOTICE,
'Undefined variable: i',
);
コールバックが複数のエラーを生成する場合、それらすべてを正確な順序で期待する必要があります。その場合、$type
に配列を渡します。
Assert::error(function () {
$a++;
$b++;
}, [
[E_NOTICE, 'Undefined variable: a'],
[E_NOTICE, 'Undefined variable: b'],
]);
$type
としてクラス名を指定した場合、Assert::exception()
と同じように動作します。
Assert::noError (callable $callable)
関数 $callable
が警告、エラー、または例外を生成しなかったことを確認します。他のアサーションがないコード片をテストする場合に役立ちます。
Assert::match (string $pattern, $actual, ?string $description=null)
$actual
はパターン $pattern
に一致しなければなりません。2
つのバリアントのパターンを使用できます:正規表現またはワイルドカード。
$pattern
として正規表現を渡す場合、その区切り文字として ~
または
#
を使用する必要があります。他の区切り文字はサポートされていません。たとえば、$var が 16
進数のみを含む必要がある場合のテスト:
Assert::match('#^[0-9a-f]$#i', $var);
2 番目のバリアントは通常の文字列比較に似ていますが、$pattern
でさまざまなワイルドカードを使用できます。
%a%
1 つ以上の文字、改行文字を除く%a?%
ゼロ個以上の文字、改行文字を除く%A%
1 つ以上の文字、改行文字を含む%A?%
ゼロ個以上の文字、改行文字を含む%s%
1 つ以上の空白文字、改行文字を除く%s?%
ゼロ個以上の空白文字、改行文字を除く%S%
1 つ以上の空白文字以外の文字%S?%
ゼロ個以上の空白文字以外の文字%c%
任意の 1 文字、改行文字を除く%d%
1 つ以上の数字%d?%
ゼロ個以上の数字%i%
符号付き整数値%f%
浮動小数点数%h%
1 つ以上の 16 進数%w%
1 つ以上の英数字%%
% 文字
例:
# 再び 16 進数のテスト
Assert::match('%h%', $var);
# ファイルパスと行番号の一般化
Assert::match('Error in file %a% on line %i%', $errorMessage);
Assert::matchFile (string $file, $actual, ?string $description=null)
アサーションは Assert::match() と同じですが、パターンはファイル
$file
から読み込まれます。これは、非常に長い文字列をテストする場合に役立ちます。テストファイルは明確なままです。
Assert::fail (string $message, $actual=null, $expected=null)
このアサーションは常に失敗します。時にはそれが役立ちます。オプションで、期待値と実際の値を指定することもできます。
期待値
非定数要素を持つより複雑な構造を比較したい場合、上記のアサーションでは不十分な場合があります。たとえば、新しいユーザーを作成し、その属性を配列として返すメソッドをテストします。パスワードハッシュの値はわかりませんが、それが
16 進文字列でなければならないことはわかっています。そして、別の要素については、それが
DateTime
オブジェクトでなければならないことしかわかりません。
これらの状況では、Assert::equal()
および Assert::notEqual()
メソッドの
$expected
パラメータ内で Tester\Expect
を使用できます。これにより、構造を簡単に記述できます。
use Tester\Expect;
Assert::equal([
'id' => Expect::type('int'), # 整数を期待します
'username' => 'milo',
'password' => Expect::match('%h%'), # パターンに一致する文字列を期待します
'created_at' => Expect::type(DateTime::class), # クラスのインスタンスを期待します
], User::create(123, 'milo', 'RandomPaSsWoRd'));
Expect
を使用すると、Assert
とほぼ同じアサーションを実行できます。つまり、メソッド
Expect::same()
、Expect::match()
、Expect::count()
などが利用可能です。さらに、それらを連鎖させることができます。
Expect::type(MyIterator::class)->andCount(5); # MyIterator と要素数 5 を期待します
または、独自のアサーションハンドラを作成することもできます。
Expect::that(function ($value) {
# 期待が失敗した場合に false を返します
});
失敗したアサーションの調査
アサーションが失敗すると、Tester
は何が間違っているかを出力します。より複雑な構造を比較する場合、Tester
は比較された値のダンプを作成し、それらを output
ディレクトリに保存します。たとえば、架空のテスト Arrays.recursive.phpt
が失敗した場合、ダンプは次のように保存されます。
app/
└── tests/
├── output/
│ ├── Arrays.recursive.actual # 実際の値
│ └── Arrays.recursive.expected # 期待値
│
└── Arrays.recursive.phpt # 失敗したテスト
ディレクトリ名は Tester\Dumper::$dumpDir
を介して変更できます。