mikail10000000's avatar

Validation auth and functional test in one method?

Hi, I'm trying to figure out the right way of testing, currently when I test things I do it in the following test, I would write a method testPostCanBeCreated() and in that method I would test if the post can be created $this->ajax('post','post',['title'=>'some text']) , plus if the post can be created with the right permissions ->assertStatus(403) and if the post can only be created with the right data ->assertStatus(422) , is this the right way ? here is the snippet of one of my code:

public function testOnlyProfileOwnerAndAdminCanMarkImageAsMain()
{
        $this->signIn(create('App\User'));
        

        $this->ajax('post','profile-image',[
          'profile_id' => 1,
          'images' => [
                UploadedFile::fake()->image('image.png', 600, 600),
                UploadedFile::fake()->image('image2.png', 600, 600)
            ],
        ])
        ->assertSuccessful();

        // check if image can be marked as main 

        $this->ajax('put','/profile-image/1',['main' => true])->assertSuccessful();
        $this->assertTrue(\App\ProfileImage::find(1)->main == true);
        $this->ajax('get','/profile-image')->assertJson([['id' => 1]]);

        //mark another image as main

        $this->ajax('put','/profile-image/2',['main' => true])->assertSuccessful();
        $this->assertTrue(\App\ProfileImage::find(1)->main == false);
        $this->assertTrue(\App\ProfileImage::find(2)->main == true);
        $this->ajax('get','/profile-image')->assertJson([['id' => 2]]);
        
        // make sure that an other user can't modify the image that does not belong to him
        auth()->logout();
        $this->signIn(create('App\User'))->ajax('put','/profile-image/2',['main' => true])
        ->assertStatus(403);
         
}

should I split it in a few separate tests, or is it the right practice ? Thank You

0 likes
3 replies
m7vm7v's avatar
m7vm7v
Best Answer
Level 51

It is a personal preferences in the end of the day.

What I would do is following what Jeffrey has shown us in the TDD lessons. I would separate the test into smaller more easily understandable-readable tests. For example if I have 2 fields that need validation I would create 2 tests for each a_post_requires_a_title so after once tested this then in the an_authenticated_user_can_create_new_forum_post you do will just send a validation friendly data as you already know it is fine.

Smaller test - better readability, easier to understand if you go again in 6 months fo a change or someone else picks it, and then if a functionality is changed then only the small piece of test would be amended rather than going trough the big test - for example later on the client decides that the title is not only required as you have tested in a_post_requires_a_title but also it needs atleast 20 chars - then you would go to the 'big' test and amend it rather than just creating additional small test for the or amending the a_post_requires_a_title with a better title of course.

When you separate the big test into smaller then you will find out that all the comments you have placed could be actually removed entirely as that will be explained in the test name itself.

In addition try creating some helper functions.

Hope that helps.

1 like

Please or to participate in this conversation.