期望

通过使用 Pest 期望 API 为您的测试设置期望,您可以轻松识别代码中的错误和其他问题。这是因为 API 允许您指定测试的预期结果,从而轻松检测任何与预期行为的偏差。

您可以通过将您的值传递给 expect($value) 函数来开始期望。每次您想要测试一个值时,都会使用 expect() 函数。您很少会单独调用 expect()。相反,您将与“期望”方法一起使用 expect() 来断言有关该值的内容。

1test('sum', function () {
2 $value = sum(1, 2);
3 
4 expect($value)->toBe(3); // Assert that the value is 3...
5});

如演示所示,Pest 中的 expect 函数允许您为给定的 $value 链接多个期望。这意味着您可以通过简单地继续链接其他期望,在一个测试中执行尽可能多的检查。

1expect($value)
2 ->toBeInt()
3 ->toBe(3);

在任何时候,您都可以通过在期望之前添加 not 修饰符来测试期望的反面。

1expect($value)
2 ->toBeInt()
3 ->toBe(3)
4 ->not->toBeString() // Not to be string...
5 ->not->toBe(4); // Not to be 4...

使用 Pest 期望 API,您可以访问大量旨在测试代码各个方面的单个期望。以下是可用期望的完整列表。

除了 Pest 中提供的单个期望外,期望 API 还提供了一些修饰符,允许您进一步自定义测试。这些修饰符可用于创建更复杂的期望并一次测试多个值。以下是 Pest 中提供的修饰符的一些示例


toBe()

此期望确保 $value$expected 具有相同的类型和值。

如果与对象一起使用,它确保两个变量都引用完全相同的对象。

1expect(1)->toBe(1);
2expect('1')->not->toBe(1);
3expect(new StdClass())->not->toBe(new StdClass());

toBeBetween()

此期望确保 $value 介于 2 个值之间。它适用于 intfloatDateTime

1expect(2)->toBeBetween(1, 3);
2expect(1.5)->toBeBetween(1, 2);
3 
4$expectationDate = new DateTime('2023-09-22');
5$oldestDate = new DateTime('2023-09-21');
6$latestDate = new DateTime('2023-09-23');
7 
8expect($expectationDate)->toBeBetween($oldestDate, $latestDate);

toBeEmpty()

此期望确保 $value 为空。

1expect('')->toBeEmpty();
2expect([])->toBeEmpty();
3expect(null)->toBeEmpty();

toBeTrue()

此期望确保 $value 为真。

1expect($isPublished)->toBeTrue();

toBeTruthy()

此期望确保 $value 为真值。

1expect(1)->toBeTruthy();
2expect('1')->toBeTruthy();

toBeFalse()

此期望确保 $value 为假。

1expect($isPublished)->toBeFalse();

toBeFalsy()

此期望确保 $value 为假值。

1expect(0)->toBeFalsy();
2expect('')->toBeFalsy();

toBeGreaterThan($expected)

此期望确保 $value 大于 $expected

1expect($count)->toBeGreaterThan(20);

toBeGreaterThanOrEqual($expected)

此期望确保 $value 大于或等于 $expected

1expect($count)->toBeGreaterThanOrEqual(21);

toBeLessThan($expected)

此期望确保 $value 小于 $expected

1expect($count)->toBeLessThan(3);

toBeLessThanOrEqual($expected)

此期望确保 $value 小于或等于 $expected

1expect($count)->toBeLessThanOrEqual(2);

toContain($needles)

此期望确保所有给定的 needles 都是 $value 的元素。

1expect('Hello World')->toContain('Hello');
2expect('Pest: an elegant PHP Testing Framework')->toContain('Pest', 'PHP', 'Framework');
3expect([1, 2, 3, 4])->toContain(2, 4);

toContainEqual($needles)

此期望确保所有给定的 needles 都是 $value 的元素(在相等方面)。

1expect([1, 2, 3])->toContainEqual('1');
2expect([1, 2, 3])->toContainEqual('1', '2');

toContainOnlyInstancesOf($class)

此期望确保 $value 仅包含 $class 的实例。

1$dates = [new DateTime(), new DateTime()];
2 
3expect($dates)->toContainOnlyInstancesOf(DateTime::class);

toHaveCount(int $count)

此期望确保提供的 $count 与可迭代 $value 中的元素数量匹配。

1expect(['Nuno', 'Luke', 'Alex', 'Dan'])->toHaveCount(4);

toHaveProperty(string $name, $value = null)

此期望确保 $value 具有名为 $name 的属性。

此外,您可以通过提供第二个参数来验证属性的实际值。

1expect($user)->toHaveProperty('name');
2expect($user)->toHaveProperty('name', 'Nuno');
3expect($user)->toHaveProperty('is_active', 'true');

toHaveProperties(iterable $name)

此期望确保 $value 具有与 $names 中包含的所有名称匹配的属性名称。

1expect($user)->toHaveProperties(['name', 'email']);

此外,您可以使用关联数组验证多个属性的名称和值。

1expect($user)->toHaveProperties([
2 'name' => 'Nuno',
3 'email' => '[email protected]'
4]);

toMatchArray($array)

此期望确保 $value 数组与给定的 $array 子集匹配。

1$user = [
2 'id' => 1,
3 'name' => 'Nuno',
4 'email' => '[email protected]',
5 'is_active' => true,
6];
7 
8expect($user)->toMatchArray([
9 'email' => '[email protected]',
10 'name' => 'Nuno'
11]);

toMatchObject($object)

此期望确保 $value 对象与给定 $object 的属性的子集匹配。

1$user = new stdClass();
2$user->id = 1;
3$user->email = '[email protected]';
4$user->name = 'Nuno';
5 
6expect($user)->toMatchObject([
7 'email' => '[email protected]',
8 'name' => 'Nuno'
9]);

toEqual($expected)

此期望确保 $value$expected 具有相同的值。

1expect($title)->toEqual('Hello World');
2expect('1')->toEqual(1);
3expect(new StdClass())->toEqual(new StdClass());

toEqualCanonicalizing($expected)

此期望确保 $value$expected 具有相同的值,无论元素的顺序如何。

1$usersAsc = ['Dan', 'Fabio', 'Nuno'];
2$usersDesc = ['Nuno', 'Fabio', 'Dan'];
3 
4expect($usersAsc)->toEqualCanonicalizing($usersDesc);
5expect($usersAsc)->not->toEqual($usersDesc);

toEqualWithDelta($expected, float $delta)

此期望确保 $value$expected 之间的绝对差小于 $delta

1expect($durationInMinutes)->toEqualWithDelta(10, 5); //duration of 10 minutes with 5 minutes tolerance
2 
3expect(14)->toEqualWithDelta(10, 5); // Pass
4expect(14)->toEqualWithDelta(10, 0.1); // Fail

toBeIn()

此期望确保 $value 是给定值之一。

1expect($newUser->status)->toBeIn(['pending', 'new', 'active']);

toBeInfinite()

此期望确保 $value 为无限。

1expect(log(0))->toBeInfinite();

toBeInstanceOf($class)

此期望确保 $value$class 的实例。

1expect($user)->toBeInstanceOf(User::class);

toBeArray()

此期望确保 $value 是一个数组。

1expect(['Pest','PHP','Laravel'])->toBeArray();

toBeBool()

此期望确保 $value 的类型为 bool。

1expect($isActive)->toBeBool();

toBeCallable()

此期望确保 $value 的类型为 callable。

1$myFunction = function () {};
2 
3expect($myFunction)->toBeCallable();

toBeFile()

此期望确保字符串 $value 是一个现有的文件。

1expect('/tmp/some-file.tmp')->toBeFile();

toBeFloat()

此期望确保 $value 的类型为 float。

1expect($height)->toBeFloat();

toBeInt()

此期望确保 $value 的类型为 integer。

1expect($count)->toBeInt();

toBeIterable()

此期望确保 $value 的类型为 iterable。

1expect($array)->toBeIterable();

toBeNumeric()

此期望确保 $value 的类型为 numeric。

1expect($age)->toBeNumeric();
2expect(10)->toBeNumeric();
3expect('10')->toBeNumeric();

toBeDigits()

此期望确保 $value 只包含数字。

1expect($year)->toBeDigits();
2expect(15)->toBeDigits();
3expect('15')->toBeDigits();

toBeObject()

此期望确保 $value 的类型为 object。

1$object = new stdClass();
2 
3expect($object)->toBeObject();

toBeResource()

此期望确保$value的类型为资源。

1$handle = fopen('php://memory', 'r+');
2 
3expect($handle)->toBeResource();

toBeScalar()

此期望确保$value的类型为标量。

1expect('1')->toBeScalar();
2expect(1)->toBeScalar();
3expect(1.0)->toBeScalar();
4expect(true)->toBeScalar();
5expect([1, '1'])->not->toBeScalar();

toBeString()

此期望确保$value的类型为字符串。

1expect($string)->toBeString();

toBeJson()

此期望确保$value是一个 JSON 字符串。

1expect('{"hello":"world"}')->toBeJson();

toBeNan()

此期望确保$value不是数字 (NaN)。

1expect(sqrt(-1))->toBeNan();

toBeNull()

此期望确保$value为 null。

1expect(null)->toBeNull();

toHaveKey(string $key)

此期望确保$value包含提供的$key

1expect(['name' => 'Nuno', 'surname' => 'Maduro'])->toHaveKey('name');
2expect(['name' => 'Nuno', 'surname' => 'Maduro'])->toHaveKey('name', 'Nuno');
3expect(['user' => ['name' => 'Nuno', 'surname' => 'Maduro']])->toHaveKey('user.name');
4expect(['user' => ['name' => 'Nuno', 'surname' => 'Maduro']])->toHaveKey('user.name', 'Nuno');

toHaveKeys(array $keys)

此期望确保$value包含提供的$keys

1expect(['id' => 1, 'name' => 'Nuno'])->toHaveKeys(['id', 'name']);
2expect(['message' => ['from' => 'Nuno', 'to' => 'Luke'] ])->toHaveKeys(['message.from', 'message.to']);

toHaveLength(int $number)

此期望确保提供的$number与字符串$value的长度或可迭代$value中元素的数量匹配。

1expect('Pest')->toHaveLength(4);
2expect(['Nuno', 'Maduro'])->toHaveLength(2);

toBeDirectory()

此期望确保字符串$value是一个目录。

1expect('/tmp')->toBeDirectory();

toBeReadableDirectory()

此期望确保字符串$value是一个目录并且它是可读的。

1expect('/tmp')->toBeReadableDirectory();

toBeReadableFile()

此期望确保字符串$value是一个文件并且它是可读的。

1expect('/tmp/some-file.tmp')->toBeReadableFile();

toBeWritableDirectory()

此期望确保字符串$value是一个目录并且它是可写的。

1expect('/tmp')->toBeWritableDirectory();

toBeWritableFile()

此期望确保字符串$value是一个文件并且它是可写的。

1expect('/tmp/some-file.tmp')->toBeWritableFile();

toStartWith(string $expected)

此期望确保$value以提供的字符串开头。

1expect('Hello World')->toStartWith('Hello');

toThrow()

此期望确保闭包抛出一个特定的异常类、异常消息或两者。

1expect(fn() => throw new Exception('Something happened.'))->toThrow(Exception::class);
2expect(fn() => throw new Exception('Something happened.'))->toThrow('Something happened.');
3expect(fn() => throw new Exception('Something happened.'))->toThrow(Exception::class, 'Something happened.');
4expect(fn() => throw new Exception('Something happened.'))->toThrow(new Exception('Something happened.'));

toMatch(string $expression)

此期望确保$value匹配正则表达式。

1expect('Hello World')->toMatch('/^hello wo.*$/i');

toEndWith(string $expected)

此期望确保$value以提供的字符串结尾。

1expect('Hello World')->toEndWith('World');

toMatchConstraint(Constraint $constraint)

此期望确保$value匹配指定的 PHPUnit 约束。

1use PHPUnit\Framework\Constraint\IsTrue;
2 
3expect(true)->toMatchConstraint(new IsTrue());

toBeUppercase(string $expected)

此期望确保$value为大写。

1expect('PESTPHP')->toBeUppercase();

toBeLowercase(string $expected)

此期望确保$value为小写。

1expect('pestphp')->toBeLowercase();

toBeAlpha(string $expected)

此期望确保$value仅包含字母字符。

1expect('pestphp')->toBeAlpha();

toBeAlphaNumeric(string $expected)

此期望确保$value仅包含字母数字字符。

1expect('pestPHP123')->toBeAlphaNumeric();

toBeSnakeCase()

此期望确保$value仅包含 snake_case 格式的字符串。

1expect('snake_case')->toBeSnakeCase();

toBeKebabCase()

此期望确保$value仅包含 kebab-case 格式的字符串。

1expect('kebab-case')->toBeKebabCase();

toBeCamelCase()

此期望确保$value仅包含 camelCase 格式的字符串。

1expect('camelCase')->toBeCamelCase();

toBeStudlyCase()

此期望确保$value仅包含 StudlyCase 格式的字符串。

1expect('StudlyCase')->toBeStudlyCase();

toHaveSnakeCaseKeys()

此期望确保$value仅包含一个键为 snake_case 格式的数组。

1expect(['snake_case' => 'abc123'])->toHaveSnakeCaseKeys();

toHaveKebabCaseKeys()

此期望确保$value仅包含一个键为 kebab-case 格式的数组。

1expect(['kebab-case' => 'abc123'])->toHaveKebabCaseKeys();

toHaveCamelCaseKeys()

此期望确保$value仅包含一个键为 camelCase 格式的数组。

1expect(['camelCase' => 'abc123'])->toHaveCamelCaseKeys();

toHaveStudlyCaseKeys()

此期望确保$value仅包含一个键为 StudlyCase 格式的数组。

1expect(['StudlyCase' => 'abc123'])->toHaveStudlyCaseKeys();

toHaveSameSize()

此期望确保$value的大小与提供的可迭代对象的大小相同。

1expect(['foo', 'bar'])->toHaveSameSize(['baz', 'bazz']);

toBeUrl()

此期望确保$value是一个 URL。

1expect('https://pest.php.net/')->toBeUrl();

toBeUuid()

此期望确保$value是一个 UUID。

1expect('ca0a8228-cdf6-41db-b34b-c2f31485796c')->toBeUuid();

and($value)

and() 修饰符允许您传递一个新的 $value,使您能够在一个测试中链接多个期望。

1expect($id)->toBe(14)
2 ->and($name)->toBe('Nuno');

dd()

dd() 修饰符

使用 dd() 修饰符允许您转储当前期望的 $value 并停止代码执行。这可以通过允许您在测试中的特定点检查 $value 的当前状态来帮助调试。

1expect(14)->dd(); // 14
2expect([1, 2])->sequence(
3 fn ($number) => $number->toBe(1),
4 fn ($number) => $number->dd(), // 2
5);

ddWhen($condition)

使用 ddWhen() 修饰符允许您转储当前期望的 $value 并停止代码执行,前提是给定的 $condition 为真。

1expect([1, 2])->each(
2 fn ($number) => $number->ddWhen(fn (int $number) => $number === 2) // 2
3);

ddUnless($condition)

使用 ddUnless() 修饰符允许您转储当前期望的 $value 并停止代码执行,前提是给定的 $condition 为假。

1expect([1, 2])->each(
2 fn ($number) => $number->ddUnless(fn (int $number) => $number === 1) // 2
3);

each()

each() 修饰符允许您为给定可迭代对象的每个项目创建期望。它的工作原理是遍历可迭代对象并将期望应用于每个项目。

1expect([1, 2, 3])->each->toBeInt();
2expect([1, 2, 3])->each->not->toBeString();
3expect([1, 2, 3])->each(fn ($number) => $number->toBeLessThan(4));

json()

json() 修饰符将当前期望的 $value 从 JSON 解码为数组。

1expect('{"name":"Nuno","credit":1000.00}')
2 ->json()
3 ->toHaveCount(2)
4 ->name->toBe('Nuno')
5 ->credit->toBeFloat();
6 
7expect('not-a-json')->json(); //Fails

match()

match() 修饰符执行与第一个参数给定方法的值匹配的第一个数组键关联的闭包。

1expect($user->miles)
2 ->match($user->status, [
3 'new' => fn ($userMiles) => $userMiles->ToBe(0),
4 'gold' => fn ($userMiles) => $userMiles->toBeGreaterThan(500),
5 'platinum' => fn ($userMiles) => $userMiles->toBeGreaterThan(1000),
6 ]);

要检查期望值是否等于与匹配键关联的值,您可以直接将期望值作为数组值传递,而不是使用闭包。

1expect($user->default_language)
2 ->match($user->country, [
3 'PT' => 'Português',
4 'US' => 'English',
5 'TR' => 'Türkçe',
6 ]);

not

not 修饰符允许反转后续期望。

1expect(10)->not->toBeGreaterThan(100);
2expect(true)->not->toBeFalse();

ray()

ray() 修饰符允许您使用 myray.app 调试当前的 $value

1expect(14)->ray(); // 14
2expect([1, 2])->sequence(
3 fn ($number) => $number->toBe(1),
4 fn ($number) => $number->ray(), // 2
5);

sequence()

sequence() 修饰符允许您为单个可迭代对象指定一组顺序期望。

1expect([1, 2, 3])->sequence(
2 fn ($number) => $number->toBe(1),
3 fn ($number) => $number->toBe(2),
4 fn ($number) => $number->toBe(3),
5);

sequence() 修饰符也可以与关联可迭代对象一起使用。序列中的每个闭包将接收两个参数:第一个参数是值的期望,第二个参数是键的期望。

1expect(['hello' => 'world', 'foo' => 'bar', 'john' => 'doe'])->sequence(
2 fn ($value, $key) => $value->toEqual('world'),
3 fn ($value, $key) => $key->toEqual('foo'),
4 fn ($value, $key) => $value->toBeString(),
5);

sequence() 修饰符也可用于检查可迭代对象中的每个值是否与一组期望值匹配。在这种情况下,您可以将期望值直接传递给 sequence() 方法,而不是使用闭包。

1expect(['foo', 'bar', 'baz'])->sequence('foo', 'bar', 'baz');

when()

when() 修饰符在传递给方法的第一个参数计算结果为真时运行提供的回调函数。

1expect($user)
2 ->when($user->is_verified === true, fn ($user) => $user->daily_limit->toBeGreaterThan(10))
3 ->email->not->toBeEmpty();

unless()

unless() 修饰符在传递给方法的第一个参数计算结果为假时运行提供的回调函数。

1expect($user)
2 ->unless($user->is_verified === true, fn ($user) => $user->daily_limit->toBe(10))
3 ->email->not->toBeEmpty();

在学习了如何编写期望之后,文档中的下一部分“钩子”涵盖了诸如“beforeEach”和“afterEach”之类的有用函数,这些函数可用于为测试设置前提条件和清理操作: 钩子 →