İddialar

Aassertions, gerçek bir değerin beklenen bir değerle eşleştiğini iddia etmek için kullanılır. Bunlar Tester\Assert'un yöntemleridir.

En doğru iddiaları seçin. Assert::same($a, $b) , Assert::true($a === $b) 'den daha iyidir çünkü başarısızlık durumunda anlamlı bir hata mesajı görüntüler. İkinci durumda sadece false should be true alırız ve $a ve $b değişkenlerinin içeriği hakkında hiçbir şey söylemez.

Çoğu iddia, beklentinin başarısız olması durumunda hata mesajında görünen isteğe bağlı bir $description adresine de sahip olabilir.

Örnekler aşağıdaki sınıf takma adının tanımlandığını varsayar:

use Tester\Assert;

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

$expected $actual ile aynı olmalıdır. PHP operatörü ile aynıdır ===.

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

Assert::same()'un tersidir, bu nedenle PHP operatörü !== ile aynıdır.

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

$expected $actual ile aynı olmalıdır. Assert::same() adresinden farklı olarak, nesne kimliği, dizilerdeki anahtar çiftleri ⇒ değer sırası ve marjinal olarak farklı ondalık sayılar göz ardı edilir; bunlar $matchIdentity ve $matchOrder adresleri ayarlanarak değiştirilebilir.

Aşağıdaki durumlar equal() açısından aynıdır, ancak same() için aynı değildir:

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

Ancak, dikkat edin, dizi [1, 2] ve [2, 1] eşit değildir, çünkü anahtar ⇒ değer çiftleri değil, yalnızca değerlerin sırası farklıdır. Dizi [1, 2] olarak da yazılabilir [0 => 1, 1 => 2] ve bu nedenle [1 => 2, 0 => 1] eşit kabul edilecektir.

Sözde beklentileri $expected adresinde de kullanabilirsiniz.

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

Karşısında Assert::equal().

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

$actual bir dizeyse, $needle alt dizesini içermelidir. Bir dizi ise, $needle öğesini içermelidir (kesinlikle karşılaştırılır).

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

Karşısında Assert::contains().

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

$actual bir dizi olmalı ve $needle anahtarını içermelidir.

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

$actual bir dizi olmalı ve $needle anahtarını içermemelidir.

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

$value true , yani $value === true olmalıdır.

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

$value doğru olmalıdır, bu nedenle if ($value) ... koşulunu karşılar.

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

$value false , yani $value === false olmalıdır.

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

$value falsey olmalıdır, bu nedenle if (!$value) ... koşulunu karşılar.

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

$value null , yani $value === null olmalıdır.

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

$value null olmamalıdır, bu yüzden $value !== null.

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

$value Bir Numara Değil olmalıdır. NAN testi için yalnızca Assert::nan() adresini kullanın. NAN değeri çok spesifiktir ve Assert::same() veya Assert::equal() iddiaları tahmin edilemeyecek şekilde davranabilir.

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

$value adresindeki öğe sayısı $count olmalıdır. Yani count($value) === $count ile aynı.

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

$value belirli bir tipte olmalıdır. $type olarak string kullanabiliriz:

  • array
  • list – sıfırdan itibaren sayısal anahtarların artan sırasına göre dizinlenmiş dizi
  • bool
  • callable
  • float
  • int
  • null
  • object
  • resource
  • scalar
  • string
  • sınıf adını veya nesnesini doğrudan geçmelidir. $value instanceof $type

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

$callable çağrıldığında $class örneğinin bir istisnası fırlatılmalıdır. Eğer $message adresini geçersek, istisnanın mesajı eşleşmelidir. Ve eğer $code adresini geçersek, istisnanın kodu aynı olmalıdır.

Örneğin, istisnanın mesajı eşleşmediği için bu test başarısız olur:

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

Assert::exception() atılan bir istisna döndürür, böylece iç içe geçmiş bir istisnayı test edebilirsiniz.

$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 çağrısının beklenen hataları (yani uyarılar, bildirimler, vb.) oluşturup oluşturmadığını kontrol eder. $type olarak E_... sabitlerinden birini belirtiriz, örneğin E_WARNING. Ve eğer $message geçilirse, hata mesajı da kalıpla eşleşmelidir. Örneğin:

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

Geri arama daha fazla hata üretirse, hepsini tam sırayla beklemeliyiz. Bu durumda diziyi $type adresine aktarırız:

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

Eğer $type sınıf adı ise, bu iddia Assert::exception() ile aynı şekilde davranır.

Assert::noError(callable $callable)

$callable işlevinin herhangi bir PHP uyarısı/bildirimi/hatası veya istisnası atmadığını kontrol eder. Başka bir iddianın olmadığı bir kod parçasını test etmek için kullanışlıdır.

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

$actual $pattern ile eşleşmelidir. İki çeşit kalıp kullanabiliriz: düzenli ifadeler veya joker karakterler.

Bir düzenli ifadeyi $pattern olarak geçirirsek, sınırlandırmak için ~ or # kullanmalıyız. Diğer sınırlayıcılar desteklenmez. Örneğin, $var adresinin yalnızca onaltılık basamaklar içermesi gereken test:

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

Diğer varyant dize karşılaştırmaya benzer ancak $pattern adresinde bazı vahşi karakterler kullanabiliriz:

  • %a% satır sonu karakterleri hariç herhangi bir şeyden bir veya daha fazlası
  • %a?% satır sonu karakterleri dışında herhangi bir şeyden sıfır veya daha fazlası
  • %A% satır sonu karakterleri de dahil olmak üzere herhangi bir şeyden bir veya daha fazlası
  • %A?% satır sonu karakterleri de dahil olmak üzere herhangi bir şeyden sıfır veya daha fazlası
  • %s% satır sonu karakterleri hariç bir veya daha fazla beyaz boşluk karakteri
  • %s?% satır sonu karakterleri hariç sıfır veya daha fazla beyaz boşluk karakteri
  • %S% beyaz boşluk hariç bir veya daha fazla karakter
  • %S?% beyaz boşluk dışında sıfır veya daha fazla karakter
  • %c% herhangi bir türden tek bir karakter (satır sonu hariç)
  • %d% bir veya daha fazla rakam
  • %d?% sıfır veya daha fazla basamak
  • %i% işaretli tamsayı değeri
  • %f% kayan nokta sayısı
  • %h% bir veya daha fazla HEX rakamı
  • %w% bir veya daha fazla alfanümerik karakter
  • %% bir % karakteri

Örnekler:

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

Assert::match() ile aynıdır ancak kalıp $file adresinden yüklenir. Çok uzun dizeleri test etmek için kullanışlıdır. Test dosyası okunabilir duruyor.

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

Bu iddia her zaman başarısız olur. Sadece kullanışlıdır. İsteğe bağlı olarak beklenen ve gerçek değerleri geçebiliriz.

Beklentiler

Sabit olmayan elemanlara sahip daha karmaşık yapıları karşılaştırmak istiyorsak, yukarıdaki ifadeler yeterli olmayabilir. Örneğin, yeni bir kullanıcı oluşturan ve özniteliklerini bir dizi olarak döndüren bir yöntemi test ediyoruz. Parola karma değerini bilmiyoruz, ancak onaltılık bir dize olması gerektiğini biliyoruz. Ve bir sonraki eleman hakkında bildiğimiz tek şey, bunun bir nesne olması gerektiğidir DateTime.

Bu durumlarda, yapıyı kolayca tanımlamak için kullanılabilecek Assert::equal() ve Assert::notEqual() yöntemlerinin $expected parametresinin içindeki Tester\Expect 'u kullanabiliriz.

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'));

Expect ile, Assert ile hemen hemen aynı iddialarda bulunabiliriz. Yani Expect::same(), Expect::match(), Expect::count(), vb. gibi metotlarımız var. Ek olarak, bunları şu şekilde zincirleyebiliriz:

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

Ya da kendi onaylama işleyicilerini yazabiliriz.

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

Başarısız İddialar Soruşturması

Tester, bir iddia başarısız olduğunda hatanın nerede olduğunu gösterir. Karmaşık yapıları karşılaştırdığımızda, Tester karşılaştırılan değerlerin dökümlerini oluşturur ve bunları output dizinine kaydeder. Örneğin hayali test Arrays.recursive.phpt başarısız olduğunda dökümler aşağıdaki gibi kaydedilecektir:

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

Dizinin adını Tester\Dumper::$dumpDir adresinden değiştirebiliriz.