Trditve

Trditve se uporabljajo za potrjevanje, da se dejanska vrednost ujema s pričakovano vrednostjo. To so metode Tester\Assert.

Izberite najnatančnejše trditve. Je boljša Assert::same($a, $b) kot Assert::true($a === $b), ker ob neuspehu prikaže smiselno sporočilo o napaki. V drugem primeru dobimo samo false should be true in ta ne pove ničesar o vsebini spremenljivk $a in $b.

Večina trditev ima lahko tudi neobvezno $description, ki se prikaže v sporočilu o napaki, če pričakovanje ni uspešno.

Primeri predpostavljajo, da je definiran naslednji vzdevek razreda:

use Tester\Assert;

Assert::same ($expected, $actual, ?string $description=null)

$expected mora biti enak kot $actual. Je enak kot operator PHP ===.

Assert::notSame ($expected, $actual, ?string $description=null)

Nasproten kot Assert::same(), zato je enak operatorju PHP !==.

Assert::equal ($expected, $actual, ?string $description=null, bool $matchOrder=false, bool $matchIdentity=false)

$expected mora biti enak kot $actual. Za razliko od Assert::same() se identiteta predmetov, vrstni red parov ključ ⇒ vrednost v poljih in mejno različna decimalna števila ne upoštevajo, kar je mogoče spremeniti z nastavitvijo $matchIdentity in $matchOrder.

Naslednji primeri so enaki z vidika equal(), ne pa tudi za same():

Assert::equal(0.3, 0.1 + 0.2);
Assert::equal($obj, clone $obj);
Assert::equal(
	['first' => 11, 'second' => 22],
	['second' => 22, 'first' => 11],
);

Vendar pazite, da se polje [1, 2] in [2, 1] nista enaki, saj se razlikuje le vrstni red vrednosti, ne pa tudi pari ključ ⇒ vrednost. Polje [1, 2] lahko zapišemo tudi kot [0 => 1, 1 => 2] in zato [1 => 2, 0 => 1] bo veljalo za enako.

Uporabite lahko tudi tako imenovana pričakovanja v $expected.

Assert::notEqual ($expected, $actual, ?string $description=null)

Nasprotno od Assert::equal().

Assert::contains ($needle, string|array $actual, ?string $description=null)

Če je $actual niz, mora vsebovati podredni niz $needle. Če je polje, mora vsebovati element $needle (primerja se strogo).

Assert::notContains ($needle, string|array $actual, ?string $description=null)

Nasprotje Assert::contains().

Assert::hasKey (string|int $needle, array $actual, ?string $description=null)

$actual mora biti polje in mora vsebovati ključ $needle.

Assert::notHasKey (string|int $needle, array $actual, ?string $description=null)

$actual mora biti polje in ne sme vsebovati ključa $needle.

Assert::true ($value, ?string $description=null)

$value mora biti true, torej $value === true.

Assert::truthy ($value, ?string $description=null)

$value mora biti resničen, zato izpolnjuje pogoj if ($value) ....

Assert::false ($value, ?string $description=null)

$value mora biti false, torej $value === false.

Assert::falsey ($value, ?string $description=null)

$value mora biti falsey, zato izpolnjuje pogoj if (!$value) ....

Assert::null ($value, ?string $description=null)

$value mora biti null, torej $value === null.

Assert::notNull ($value, ?string $description=null)

$value ne sme biti null, torej $value !== null.

Assert::nan ($value, ?string $description=null)

$value ne sme biti številka. Za testiranje NAN uporabite samo Assert::nan(). Vrednost NAN je zelo specifična in trditve Assert::same() ali Assert::equal() se lahko obnašajo nepredvidljivo.

Assert::count ($count, Countable|array $value, ?string $description=null)

Število elementov v $value mora biti $count. Torej enako kot count($value) === $count.

Assert::type (string|object $type, $value, ?string $description=null)

$value mora biti določene vrste. Kot $type lahko uporabimo niz:

  • array
  • list – polje, indeksirano v naraščajočem vrstnem redu številskih ključev od nič
  • bool
  • callable
  • float
  • int
  • null
  • object
  • resource
  • scalar
  • string
  • ime razreda ali predmeta neposredno, potem mora posredovati $value instanceof $type

Assert::exception (callable $callable, string $class, ?string $message=null, $code=null)

Ob klicu $callable je treba zavreči izjemo primera $class. Če posredujemo $message, se mora sporočilo izjeme ujemati. In če posredujemo $code, mora biti koda izjeme enaka.

Na primer, ta preskus ni uspešen, ker se sporočilo izjeme ne ujema:

Assert::exception(
	fn() => throw new App\InvalidValueException('Zero value'),
	App\InvalidValueException::class,
	'Value is to low',
);

Assert::exception() vrne vrnjeno izjemo, zato lahko testirate vgnezdeno izjemo.

$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)

Preveri, ali klic $callable ustvari pričakovane napake (tj. opozorila, obvestila itd.). Kot $type navedemo eno od konstant E_..., na primer E_WARNING. In če predamo $message, mora tudi sporočilo o napaki ustrezati vzorcu. For example:

Assert::error(
	fn() => $i++,
	E_NOTICE,
	'Undefined variable: i',
);

Če povratni klic ustvari več napak, moramo pričakovati vse napake v točno določenem vrstnem redu. V tem primeru posredujemo polje v $type:

Assert::error(function () {
	$a++;
	$b++;
}, [
	[E_NOTICE, 'Undefined variable: a'],
	[E_NOTICE, 'Undefined variable: b'],
]);

Če je $type ime razreda, se ta trditev obnaša enako kot Assert::exception().

Assert::noError (callable $callable)

Preveri, ali funkcija $callable ne vrže nobenega opozorila/opozorila/pomote ali izjeme PHP. Uporabna je za testiranje dela kode, v katerem ni nobene druge trditve.

Assert::match (string $pattern, $actual, ?string $description=null)

$actual se mora ujemati z $pattern. Uporabimo lahko dve različici vzorcev: regularne izraze ali nadomestne znake.

Če posredujemo regularni izraz kot $pattern, moramo za njegovo razmejitev uporabiti ~ or #. Drugi delilniki niso podprti. Na primer test, pri katerem mora $var vsebovati samo šestnajstiške številke:

Assert::match('#^[0-9a-f]$#i', $var);

Druga različica je podobna primerjanju nizov, vendar lahko v $pattern uporabimo nekatere divje znake:

  • %a% enega ali več znakov, razen znakov za konec vrstice
  • %a?% nič ali več znakov, razen znakov za konec vrstice
  • %A% en ali več česar koli, vključno z znaki za konec vrstice
  • %A?% nič ali več znakov, vključno z znaki za konec vrstice
  • %s% en ali več znakov belega prostora, razen znakov za konec vrstice
  • %s?% nič ali več znakov belega prostora, razen znakov za konec vrstice
  • %S% en ali več znakov, razen belega presledka
  • %S?% nič ali več znakov, razen belega presledka
  • %c% en sam znak katere koli vrste (razen konca vrstice)
  • %d% ena ali več številk
  • %d?% nič ali več številk
  • %i% podpisana celoštevilska vrednost
  • %f% število s plavajočo vejico
  • %h% ena ali več številk HEX
  • %w% en ali več alfanumeričnih znakov
  • %% en znak %

Primeri:

# Again, hexadecimal number test
Assert::match('%h%', $var);

# Generalized path to file and line number
Assert::match('Error in file %a% on line %i%', $errorMessage);

Assert::matchFile (string $file, $actual, ?string $description=null)

Trditev je enaka kot Assert::match( ), vendar se vzorec naloži iz $file. Uporabna je za testiranje zelo dolgih nizov. Testna datoteka stoji berljivo.

Assert::fail (string $message, $actual=null, $expected=null)

Ta trditev je vedno neuspešna. Je pač priročna. Po želji lahko posredujemo pričakovane in dejanske vrednosti.

Pričakovanja

Če želimo primerjati bolj zapletene strukture z nekonstantnimi elementi, zgornje trditve morda ne bodo zadostovale. Preizkušamo na primer metodo, ki ustvari novega uporabnika in vrne njegove atribute kot polje. Ne poznamo vrednosti hasha gesla, vemo pa, da mora biti to šestnajstiški niz. O naslednjem elementu pa vemo le to, da mora biti objekt DateTime.

V teh primerih lahko znotraj parametra $expected metod Assert::equal() in Assert::notEqual() uporabimo Tester\Expect, s katerim lahko preprosto opišemo strukturo.

use Tester\Expect;

Assert::equal([
	'id' => Expect::type('int'),                   # we expect an integer
	'username' => 'milo',
	'password' => Expect::match('%h%'),            # we expect a string matching pattern
	'created_at' => Expect::type(DateTime::class), # we expect an instance of the class
], User::create(123, 'milo', 'RandomPaSsWoRd'));

Z metodo Expect lahko podamo skoraj enake trditve kot z metodo Assert. Tako imamo metode, kot so Expect::same(), Expect::match(), Expect::count() itd. Poleg tega jih lahko verižimo, kot npr:

Expect::type(MyIterator::class)->andCount(5);  # we expect MyIterator and items count is 5

Lahko pa napišemo tudi lastne upravljavce trditev.

Expect::that(function ($value) {
	# return false if expectation fails
});

Preiskava neuspešnih trditev

Tester pokaže, kje je napaka, ko trditev ni uspešna. Ko primerjamo kompleksne strukture, Tester ustvari izpise primerjanih vrednosti in jih shrani v imenik output. Na primer, ko namišljeni test Arrays.recursive.phpt ne uspe, se izpisi shranijo na naslednji način:

app/
└── tests/
	├── output/
	│   ├── Arrays.recursive.actual    # actual value
	│   └── Arrays.recursive.expected  # expected value
	│
	└── Arrays.recursive.phpt          # failing test

Ime imenika lahko spremenimo z Tester\Dumper::$dumpDir.