opnform-host-nginx/.cursor/rules/back-end-testing.mdc

121 lines
4.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
description: Laravel Back-end Tests
globs: api/tests/**/*.php
---
You are an expert in Laravel testing, particularly with Pest PHP for the Laravel back-end.
Key Principles
- Write concise, isolated tests that verify specific functionality.
- Follow the Arrange-Act-Assert pattern for test structure.
- Use descriptive test names that explain what is being tested.
- Prefer Pest PHP's expressive syntax over traditional PHPUnit syntax.
- Use mocking and test doubles appropriately to isolate components.
- Organize tests by the component they are testing.
Test Structure
- `tests/Feature/`: Contains feature tests that test the application as a whole.
- `tests/Unit/`: Contains unit tests that test individual components in isolation.
- `Unit/Rules/`: Tests for validation rules.
- `Unit/Service/`: Tests for service classes.
- `Unit/Services/`: Tests for service classes (alternative structure).
- `tests/Helpers/`: Contains helper classes used across tests.
- `tests/Browser/`: Contains browser tests using Laravel Dusk.
Test Configuration
- Use `tests/Pest.php` for Pest PHP configuration.
- Use `tests/TestCase.php` as the base test case class.
- Use `tests/TestHelpers.php` for common helper methods.
Unit Testing Best Practices
1. **Test in Isolation**: Mock dependencies to ensure true unit testing.
2. **Single Responsibility**: Each test should verify one specific behavior.
3. **Descriptive Names**: Use descriptive test names that explain what is being tested.
4. **Arrange-Act-Assert**: Structure tests with clear arrangement, action, and assertion phases.
5. **Test Edge Cases**: Include tests for edge cases and error conditions.
6. **Use describe()**: Group related tests using describe() blocks.
7. **Use beforeEach()**: Set up common test state using beforeEach() hooks.
8. **Avoid Test Dependencies**: Tests should not depend on the state from other tests.
9. **Test Public API**: Focus on testing the public API of classes, not implementation details.
10. **Consistent Patterns**: Follow consistent patterns for similar types of tests.
Writing Unit Tests
- Use Pest PHP's expressive syntax:
```php
it('can parse filenames', function () {
$fileName = 'example_85e16d7b-58ed-43bc-8dce-7d3ff7d69f41.png';
$parsedFilename = StorageFileNameParser::parse($fileName);
expect($parsedFilename->fileName)->toBe('example');
});
```
- Group related tests with describe():
```php
describe('StorageFile validation', function () {
it('accepts valid URLs without validation', function () {
$validator = new StorageFile();
expect($validator->passes('file', 'https://example.com/file.pdf'))->toBeTrue();
});
it('rejects files with invalid UUID format', function () {
$validator = new StorageFile();
expect($validator->passes('file', 'invalid-uuid.jpg'))->toBeFalse();
});
});
```
- Use beforeEach() for common setup:
```php
beforeEach(function () {
Storage::fake('local');
});
```
- Mock dependencies:
```php
it('rejects non-existent files', function () {
$uuid = Str::uuid();
$fileName = 'file-name_' . $uuid . '.jpg';
Storage::shouldReceive('exists')
->with('tmp/' . $uuid)
->andReturn(false);
$validator = new StorageFile();
expect($validator->passes('file', $fileName))->toBeFalse();
});
```
- Test edge cases:
```php
it('can clean non-utf characters', function () {
$fileName = 'Образец_для_заполнения_85e16d7b-58ed-43bc-8dce-7d3ff7d69f41.png';
$parsedFilename = StorageFileNameParser::parse($fileName);
expect($parsedFilename->getMovedFileName())->toBe('___85e16d7b-58ed-43bc-8dce-7d3ff7d69f41.png');
});
```
Testing Validation Rules
- Create instances of the rule class.
- Test both valid and invalid inputs.
- Verify error messages for invalid inputs.
- Test edge cases and boundary conditions.
Testing Service Classes
- Mock dependencies using Mockery.
- Test each public method in isolation.
- Verify correct behavior for both success and failure cases.
- Test edge cases and error handling.
Running Tests
- Run all tests: `php artisan test`
- Run unit tests only: `php artisan test --testsuite=Unit`
- Run a specific test file: `php artisan test --filter=StorageFileTest`
- Run tests with coverage: `php artisan test --coverage`
Debugging Tests
- Use ray() for debugging test execution.
- Use dd() or dump() for quick inspection of variables.
- Check for race conditions in asynchronous tests.
- Verify that the database is being properly reset between tests.
- Ensure that tests are not dependent on each other.