There are already so many lessons here on testing, I suggest take some of them.
Like https://laracasts.com/series/pest-driven-laravel is one, there are others.
I like general testing to look for areas to refactor.
I'm new to testing so I'm trying to figure out what I should test.
I have a CRUD for managing company details.
The application has 8 different user roles, some users can access the full CRUD, some are read only and others cannot see the company details at all.
Should I be creating 8 tests for the different user roles?
Once I've tested the authorisation, I'm guessing I should have form validation tests - if there's 10 fields on the page, do I create 10 validation tests? Or one test to cover all 10 fields?
Then there's the store/update methods, I'm guessing I assert the database contains the values.
Do you have a testing workflow for a standard CRUD as to what should be covered?
I'm not sure if I'm writing too many tests.
@ella-stinnes Sounds like data providers and/or the “test with” utility would be a good solution for your use cases. They basically let you re-run a single test case multiple times, but with a different input each time.
The application has 8 different user roles, some users can access the full CRUD, some are read only and others cannot see the company details at all.
Should I be creating 8 tests for the different user roles?
Using a data provider, you’d have a single test case (e.g. test_create_company), that could take a user role and the expected result as inputs:
#[TestWith(['admin', true])]
#[TestWith(['moderator', true])]
#[TestWith(['member', false])]
// And your other roles...
public function test_create_company(string $role, bool $expected): void
{
$user = User::factory()->role($role)->createOne();
$this->assertDatabaseEmpty('companies');
$response = $this->actingAs($user)->post('/companies', [
// Valid company data...
]);
if ($expected) {
$response->assertRedirect()->assertValid();
$this->assertDatabaseHas('companies', [
// Fields and values that should exist in database...
]);
} else {
$response->assertForbidden();
$this->assertDatabaseEmpty('companies');
}
}
So the above test case will create a user with the given role and attempt to create a company. Then, depending on the expected result, will either assert the request was successful and a record was inserted into the database, or assert a 403 Forbidden response was returned and no company records were created.
Once I've tested the authorisation, I'm guessing I should have form validation tests - if there's 10 fields on the page, do I create 10 validation tests? Or one test to cover all 10 fields?
Again, you can use a data provider for say, testing required fields. For most resources in my applications, I‘ll have a test method that looks like this:
#[TestWith(['name'])]
#[TestWith(['description'])]
#[TestWith(['email'])]
#[TestWith(['telephone_number'])]
#[TestWith(['website_url'])]
public function test_field_is_required(string $field): void
{
$user = User::factory()->role('admin')->createOne();
$data = [
'name' => fake()->company(),
'email' => fake()->safeEmail(),
// All other fields with a valid value...
];
Arr::forget($data, $field);
$this
->actingAs($user)
->post('/companies', $data)
->assertInvalid($field);
}
The above test case will then be re-ran multiple times with a different field name provided as an argument each time. The test case has an array of “valid” data, but then removes the named field, and asserts the request throws a validation error for that named field.
Please or to participate in this conversation.