{
    "app": {
        "name": "pest-testing-framework",
        "description": "Integration with the Pest PHP testing framework for writing and running tests",
        "mode": "advanced-chat",
        "model_config": {
            "provider": "deepseek",
            "model": "deepseek-chat",
            "parameters": {
                "temperature": 0.7,
                "max_tokens": 4096
            }
        }
    },
    "instructions": "name Pest Testing Framework description Integration with the Pest PHP testing framework for writing and running tests color pink Running tests: php ./vendor/bin/pest Running specific tests: php ./vendor/bin/pest tests/MyTest.php Overview Pest is an elegant PHP testing framework with a focus on simplicity. It's built on top of PHPUnit but provides a more expressive and developer-friendly syntax. Running Tests Basic Commands # Run all tests php ./vendor/bin/pest # Run tests in a specific directory php ./vendor/bin/pest tests/Unit # Run a specific test file php ./vendor/bin/pest tests/HeroComponentsTest.php # Run tests with coverage php ./vendor/bin/pest --coverage # Run tests with coverage and minimum threshold php ./vendor/bin/pest --coverage --min=80 # Run tests in parallel (faster execution) php ./vendor/bin/pest --parallel # Run tests with verbose output php ./vendor/bin/pest -v # Run tests and stop on first failure php ./vendor/bin/pest --stop-on-failure # Run tests matching a filter php ./vendor/bin/pest --filter= \"HeroComponents\" Test Structure Basic Test File <?php // tests/ExampleTest.php test ( 'example test' , function () { expect ( true )-> toBeTrue (); }); it ( 'can perform assertions' , function () { $result = 2 + 2 ; expect ( $result )-> toBe ( 4 ); }); Organized Tests with describe() <?php describe ( 'HeroComponents' , function () { it ( 'renders correctly' , function () { // Test implementation }); it ( 'handles empty state' , function () { // Test implementation }); }); Using beforeEach() and afterEach() <?php beforeEach (function () { // Setup code that runs before each test $this ->user = createUser (); }); afterEach (function () { // Cleanup code that runs after each test $this ->user = null ; }); test ( 'user can login' , function () { expect ( $this ->user)->not-> toBeNull (); }); Common Expectations Value Assertions expect ( $value )-> toBe ( $expected ); // Strict equality (===) expect ( $value )-> toEqual ( $expected ); // Loose equality (==) expect ( $value )-> toBeTrue (); expect ( $value )-> toBeFalse (); expect ( $value )-> toBeNull (); expect ( $value )-> toBeEmpty (); expect ( $value )-> toBeGreaterThan ( 5 ); expect ( $value )-> toBeLessThan ( 10 ); Type Assertions expect ( $value )-> toBeInt (); expect ( $value )-> toBeString (); expect ( $value )-> toBeArray (); expect ( $value )-> toBeObject (); expect ( $value )-> toBeInstanceOf ( MyClass :: class ); Array/Collection Assertions expect ( $array )-> toHaveCount ( 3 ); expect ( $array )-> toContain ( 'value' ); expect ( $array )-> toHaveKey ( 'key' ); expect ( $array )->each-> toBeString (); String Assertions expect ( $string )-> toStartWith ( 'Hello' ); expect ( $string )-> toEndWith ( 'World' ); expect ( $string )-> toContain ( 'test' ); expect ( $string )-> toMatch ( '/regex/' ); Negation expect ( $value )->not-> toBe ( 'wrong' ); expect ( $array )->not-> toBeEmpty (); Datasets Use datasets to run the same test with different inputs: <?php it ( 'can add numbers' , function ( int $a , int $b , int $expected ) { expect ( $a + $b )-> toBe ( $expected ); })-> with ([ [ 1 , 2 , 3 ], [ 5 , 5 , 10 ], [ 10 , 20 , 30 ], ]); // Named datasets it ( 'validates email' , function ( string $email ) { expect ( isValidEmail ( $email ))-> toBeTrue (); })-> with ([ 'valid email' => 'test@example.com' , 'another valid' => 'user@domain.co.uk' , ]); HTTP Requests Pest provides methods to test HTTP endpoints by simulating requests and asserting on responses. Basic GET Requests <?php it ( 'loads the homepage' , function () { $this -> get ( '/' ) -> assertOk (); }); // Can be chained in a fluent style it ( 'returns json data' ) -> get ( '/api/data' ) -> assertOk () -> assertJson ([ 'status' => 'success' ]); POST Requests <?php it ( 'posts to an action' , function () { $this -> post ( '/post-data' , [ 'foo' => 'bar' ]) -> assertOk () -> assertSee ( '\"foo\":\"bar\"' ); }); // Post JSON data it ( 'posts json to an action' , function () { $response = $this -> postJson ( '/post-data' , [ 'foo' => 'bar' ]) -> assertHeader ( 'content-type' , 'application/json' ) -> assertOk (); expect ( $response -> json ()-> json ())->foo-> toBe ( 'bar' ); }); Authenticated Requests Use actingAs() to make requests as a specific user: <?php use markhuot \\ craftpest \\ factories \\ User ; it ( 'allows authenticated users to access protected pages' , function () { $user = User :: factory ()-> create (); $this -> actingAs ( $user ) -> get ( '/admin/settings' ) -> assertOk (); }); // Shorthand for admin users it ( 'allows admins to access settings' ) -> actingAsAdmin () -> get ( '/admin/settings' ) -> assertOk (); Common Response Assertions <?php // Status codes -> assertOk () // 200 -> assertCreated () // 201 -> assertForbidden () // 403 -> assertNotFound () // 404 // Content assertions -> assertSee ( 'text' ) // Response contains text -> assertDontSee ( 'text' ) // Response doesn't contain text // JSON assertions -> assertJson ([ 'key' => 'value' ]) // Contains JSON subset -> assertExactJson ([ 'key' => 'value' ]) // Exact JSON match -> assertJsonPath ( 'foo' , 'bar' ) // Assert value at path -> assertJsonCount ( 2 ) // Assert JSON array count -> assertJsonStructure ([ 'foo' , 'bar' ]) // Assert JSON structure -> assertJsonFragment ([ 'baz' => 'qux' ]) // Contains JSON fragment -> assertJsonMissing ([ 'missing' ]) // JSON doesn't contain value -> assertJsonMissingPath ( 'qux' ) // Path doesn't exist // Header assertions -> assertHeader ( 'x-foo' ) // Header exists -> assertHeader ( 'x-foo' , 'bar' ) // Header has value -> assertHeaderMissing ( 'x-qux' ) // Header doesn't exist // Cookie assertions -> assertCookie ( 'cookieName' ) // Cookie exists -> assertCookie ( 'cookieName' , 'cookieValue' ) // Cookie has value -> assertCookieMissing ( 'foo' ) // Cookie doesn't exist -> assertCookieExpired ( 'cookieName' ) // Cookie is expired -> assertCookieNotExpired ( 'cookieName' ) // Cookie is valid // Other assertions -> assertDownload ( 'file.jpg' ) // Response is a download -> assertCacheTag ( 'foo' , 'baz' ) // Response has cache tags Working with Response Data <?php it ( 'processes json response data' , function () { $response = $this -> get ( '/api/users' ); // Access JSON data $data = $response -> json (); expect ( $data )-> toHaveKey ( 'users' ); // Access response content $content = $response ->content; expect ( $content )-> toContain ( 'expected text' ); }); Testing Forms and Links <?php it ( 'clicks links and follows redirects' , function () { $this -> get ( '/links' ) -> querySelector ( 'a' ) -> click () -> assertOk () -> assertSee ( 'Hello World' ); }); Best Practices for HTTP Testing Test Your Logic, Not the Framework : Focus on custom validation, rendering logic, or business rules rather than testing if Craft CMS works Use Meaningful Assertions : Assert on the actual behavior that matters to your application Clean URLs : Use relative URLs starting with / for consistency Chain Assertions : Take advantage of fluent chaining for readable tests Example of a well-focused HTTP test: <?php it ( 'validates that blog posts require a title' , function () { $this -> actingAsAdmin () -> post ( '/actions/entries/save' , [ 'sectionId' => 1 , 'typeId' => 1 , 'title' => '' , // Empty title 'slug' => 'test-post' , ]) -> assertSessionHasErrors ( 'title' ); }); Rendering Templates Directly Use ->renderTemplate() to render Twig templates directly without the overhead of a full HTTP request. This is faster and more focused than ->get() when you only need to test template output. Basic Template Rendering <?php it ( 'renders a template' , function () { $this -> renderTemplate ( 'pages/home' ) -> assertSee ( 'Welcome' ); }); // Can be chained in a fluent style it ( 'renders the hero component' ) -> renderTemplate ( '_components/hero' ) -> assertSee ( 'Hero Content' ); Passing Variables to Templates Pass variables as the second parameter, just like you would in Twig: <?php it ( 'renders a template with variables' , function () { $this -> renderTemplate ( '_components/card' , [ 'title' => 'My Card Title' , 'description' => 'Card description text' , ]) -> assertSee ( 'My Card Title' ) -> assertSee ( 'Card description text' ); }); // Pass complex data it ( 'renders a list with entries' , function () { $entries = Entry :: factory () -> section ( 'posts' ) -> count ( 3 ) -> create (); $this -> renderTemplate ( '_partials/entry-list' , [ 'entries' => $entries , ]) -> assertSee ( $entries [ 0 ]->title) -> assertSee ( $entries [ 1 ]->title) -> assertSee ( $entries [ 2 ]->title); });",
    "variables": [],
    "opening_statement": "你好，我是 pest-testing-framework，Integration with the Pest PHP testing framework fo...",
    "suggested_questions": [],
    "source": "DeepseekModel",
    "source_url": "https://deepseekmodel.com/skill?id=markhuot-craft-pest-core-llms-skill-md"
}