Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

FvsJson's avatar

Unit test all validation checks...?

I just wandering when writing unit test and lets say you have 3 types of validation on a field ie, required, number and lets say number bigger than x.

Do you write tests for every single validation rule? If so that means unit testing can balloon into crazy amounts...

0 likes
6 replies
martinbean's avatar

@fvsjson Well it depends on how much confidence you want in your application.

You can use data providers to reduce the number of test cases, as it will run the same test case but with different parameters. I use this for testing forms and their validation.

FvsJson's avatar

@martinbean thanks for the reply, I hear you and i also use data sets from time to time, I was just wander if its the norm or personal preference and like i said it could mean a balloon-ing taking place in your tests.. :P

martinbean's avatar
Level 80

@FvsJson Again, if you don’t have a test for a particular condition then it’s not covered and you won’t know if you accidentally add a typo or erroneously remove the rule completely. So again, how much you test depends on how much confidence you want in your app actually working.

Tests are to confirm your app is working as you intend to instead of just assuming everything is OK.

Tray2's avatar

I like to use a providers to test validation rules.

   /**
     * @test
     * @dataProvider storeValidationProvider
     * @param $fieldValue
     * @param $field
     */
    public function store_validation_tests($field, $fieldValue)
    {
        $book = Book::factory()->make([
            $field => $fieldValue
        ]);

        $response = $this->post('/books', $book->toArray());
        $response->assertStatus(302);
        $response->assertSessionHasErrorsIn($field);
    }

    public function storeValidationProvider()
    {
        return [
            'the title is required' => ['title', ''],
            'part must be numeric' => ['part', 'One'],
            'format_id is required' => ['format_id', ''],
            'format_id must exist in formats' => ['format_id', 100],
            'genre_id is required' => ['genre_id', ''],
            'genre_id must exist in genres' => ['genre_id', 100],
            'isbn is required' => ['isbn', ''],
            'invalid isbn10 cant be stored' => ['isbn', '123456789'],
            'invalid isbn13 cant be stored' => ['isbn', '9771234567890'],
            'released is required' => ['released', ''],
            'pages is required' => ['pages', ''],
            'pages must be numeric' => ['pages', 'Ten'],
            'blurb is required' => ['blurb', ''],
            'released cant be earlier than 1800' => ['released', 1799],
            'released cant be later than current year + 1' => ['released', Carbon::now()->addYear(2)->year],
            'reprinted cant be earlier than 1800' => ['reprinted',  1799],
            'reprinted cant be later than current year + 1' => ['reprinted', Carbon::now()->addYear(2)->year]
        ];
    }

FvsJson's avatar

@Tray2 thats cleaver :) might just copy that in another project.

1 like

Please or to participate in this conversation.