Skip to content

Commit e4dfd58

Browse files
committed
Review of Chapter 19
1 parent 5e51659 commit e4dfd58

14 files changed

Lines changed: 2102 additions & 52 deletions

File tree

app/pages/6.0/19.testing/01.why-test/docs.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
---
22
title: Why Use Automated Testing?
33
description: Learn why testing is essential for building reliable, maintainable applications.
4-
wip: true
54
---
65

76
Every developer has experienced this nightmare: You fix a bug in one part of your application, deploy it to production, and suddenly something else breaks. A "simple" change cascades into hours of debugging. Users report errors you never saw in development. You're afraid to modify code because you might break something.
87

98
**Automated testing** prevents this chaos. Tests are code that verifies your code works correctly. When you make changes, tests run automatically to catch bugs before they reach production. They act as a safety net, giving you confidence to refactor, add features, and fix bugs without fear. Good tests mean fewer production bugs, faster development, and better sleep at night.
109

11-
UserFrosting includes PHPUnit for testing, and this chapter shows you how to write effective tests that make your application more reliable and maintainable.
10+
UserFrosting provides comprehensive testing tools for both backend and frontend code:
11+
12+
- **PHPUnit** for testing PHP code — models, controllers, services, CLI commands
13+
- **Vitest** for testing frontend code — Vue components, TypeScript modules, composables, stores
14+
15+
This chapter shows you how to write effective tests across your entire application stack, making it more reliable and maintainable.
1216

1317
## Benefits of Testing
1418

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,66 @@
11
---
22
title: Running Tests
3-
wip: true
3+
description: How to execute your PHPUnit and Vitest tests, both locally and in CI/CD pipelines.
44
---
55

6-
You can execute tests using [Phpunit](https://phpunit.de) directly :
6+
UserFrosting provides two test suites: **PHPUnit** for backend PHP code and **Vitest** for frontend Vue/TypeScript code. Here's how to run both.
7+
8+
## Backend Tests (PHPUnit)
9+
10+
You can execute backend tests using [PHPUnit](https://phpunit.de) directly:
711

812
```bash
913
./vendor/bin/phpunit
1014
```
1115

16+
Or use the predefined VS Code task:
17+
18+
- Open Command Palette (`Cmd+Shift+P` on macOS, `Ctrl+Shift+P` on Windows/Linux)
19+
- Run `Tasks: Run Task`
20+
- Select `Backend - PHPUnit`
21+
1222
UserFrosting's built-in integration tests use a temporary in-memory SQLite database. For testing to run successfully, you must have the `php-sqlite3` package installed and enabled. Alternatively, you can create a separate testing database and override the `test_integration` database settings in the `testing.php` [environment mode](/configuration/config-files) from your site sprinkle.
1323

14-
When testing, only the tests define in your Sprinkle will be run. UserFrosting base system tests are run in their own repository.
24+
When testing, only the tests defined in your app will be run. UserFrosting base system tests (located in `/vendor`) are run in their own repository.
25+
26+
## Frontend Tests (Vitest)
27+
28+
Execute frontend tests using npm:
29+
30+
```bash
31+
npm run test
32+
```
33+
34+
Generate a coverage report:
35+
36+
```bash
37+
npm run coverage
38+
```
39+
40+
Or use the predefined VS Code task:
41+
42+
- Open Command Palette
43+
- Run `Tasks: Run Task`
44+
- Select `Frontend - Tests` or `Frontend - Coverage`
45+
46+
Coverage reports are typically generated in `_meta/coverage/` or `_meta/_coverage/` and can be viewed in your browser.
47+
48+
> [!TIP]
49+
> During development, use watch mode (`npm run test:watch`) to get instant feedback as you write code. Vitest will automatically re-run affected tests when you save files.
50+
51+
## Continuous Integration
52+
53+
In CI/CD pipelines, run both test suites:
54+
55+
```bash
56+
# Backend tests
57+
./vendor/bin/phpunit
58+
59+
# Frontend tests
60+
npm run test
61+
62+
# Optional: Generate coverage reports
63+
npm run coverage
64+
```
65+
66+
Many teams configure CI to fail the build if test coverage drops below a certain threshold.

app/pages/6.0/19.testing/03.writting-tests/01.testcase/docs.md renamed to app/pages/6.0/19.testing/03.writing-tests/01.testcase/docs.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Sprinkle Test Case
3-
wip: true
3+
description: Master the UserFrosting TestCase class with helper methods for testing routes, JSON responses, and HTTP requests.
44
---
55

66
To make it easier to run your tests in your Sprinkle environment, that is with every routes, middlewares and other class registered in your Recipe, UserFrosting provides a base TestCase you can use. You simply need to tell the TestCase to use your Recipe. It will create a simple UserFrosting app instance, and cleanly destroy it when the test is done. It also provides some additional helper methods.
@@ -10,7 +10,7 @@ To make it easier to run your tests in your Sprinkle environment, that is with e
1010
1111
## Integrating with your Sprinkle
1212

13-
To begin testing your Sprinkle, your test case simply need to extends `UserFrosting\Testing\TestCase`. Then, define your Sprinkle Recipe in the `$mainSprinkle` property. For example:
13+
To begin testing your Sprinkle, your test case simply needs to extend `UserFrosting\Testing\TestCase`. Then, define your Sprinkle Recipe in the `$mainSprinkle` property. For example:
1414

1515
```php
1616
<?php
@@ -31,9 +31,11 @@ class MyTest extends TestCase
3131
}
3232
```
3333

34-
You could also use the code above as a new test case, instead of defining `$mainSprinkle` in every tests. Instead of naming the class `MyTest`, name it `MyTestCase` and make every test class extend `MyTestCase`.
34+
> [!TIP]
35+
> You could also use the code above as a new test case, instead of defining `$mainSprinkle` in every tests. Instead of naming the class `MyTest`, name it `MyTestCase` and make every test class extend `MyTestCase`.
3536
36-
The biggest advantage is you don't *need* to use your Recipe. Alternatively, you can create a recipe stub. Simply create a *second* recipe in your testing directory. This other recipe can register only the class you want to test.
37+
> [!TIP]
38+
> You don't *need* to use **your** Recipe. Alternatively, you can create a recipe stub only for testing. Simply create a *second* recipe in your testing directory. This other recipe can register only the class you want to test.
3739
3840
## Helping methods & properties
3941

@@ -48,11 +50,11 @@ When extending `UserFrosting\Testing\TestCase`, you have access to many helper m
4850
| `$this->mainSprinkle` | The main sprinkle identifier |
4951

5052
> [!NOTE]
51-
> The default PHPUnit `setUp` method will create the application, while `tearDown` will delete the application. All properties needs to be access after invoking the parent method.
53+
> The default PHPUnit `setUp` method will create the application, while `tearDown` will delete the application. All properties need to be accessed after invoking the parent method.
5254
5355
### createRequest
5456

55-
This methods can be used to create a basic `ServerRequestInterface`.
57+
This method can be used to create a basic `ServerRequestInterface`.
5658

5759
```php
5860
$this->createRequest(
@@ -135,7 +137,7 @@ assertJsonResponse(mixed $expected, ResponseInterface $response, ?string $key =
135137
**Example**
136138
```php
137139
$this->assertJsonResponse(['foo' => 'bar'], $response);
138-
$this->assertJsonResponse('bar', $response), 'foo';
140+
$this->assertJsonResponse('bar', $response, 'foo');
139141

140142
// Same as
141143

app/pages/6.0/19.testing/03.writting-tests/02.Traits/docs.md renamed to app/pages/6.0/19.testing/03.writing-tests/02.Traits/docs.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Helper Traits & Class
3-
wip: true
3+
description: Discover testing utilities like ContainerStub, BakeryTester, RefreshDatabase, and WithTestUser for easier test setup.
44
---
55

66
UserFrosting provides some helper Traits to easily enable features and tools for your tests. Some of those tools make it easier to test your code against a testing database.
@@ -16,7 +16,7 @@ use App\MySite\Foo;
1616
// ...
1717

1818
$ci = ContainerStub::create();
19-
$foo = = Mockery::mock(Foo::class)
19+
$foo = Mockery::mock(Foo::class);
2020
$ci->set(Foo::class, $foo);
2121

2222
// ...
@@ -73,7 +73,7 @@ $this->assertStringContainsString('Cache cleared', $result->getDisplay());
7373
By default all tests are run against an in-memory SQLite database. This database is temporary and independent from the database used by your UserFrosting instance. That means your data is safe when tests are run. If you prefer to use a real database for tests, you can overwrite the `test_integration` connection config in your own sprinkle for the `testing` environment.
7474

7575
> [!WARNING]
76-
> While you **can** test your code against the main database, it usually not a good idea to do so with a production database. Those are _tests_ after all. They _can_ fail. **Catastrophically**. UserFrosting built-in tests are all run against a test database.
76+
> While you **can** test your code against the main database, it's usually not a good idea to do so with a production database. Those are _tests_ after all. They _can_ fail. **Catastrophically**. UserFrosting built-in tests are all run against a test database.
7777
7878
Note that the in-memory database is empty by default. If your test requires the standard tables to be up, you need to use the `UserFrosting\Sprinkle\Core\Testing\RefreshDatabase` trait to run all migrations up. You could also use the migrator service to run a particular migration up.
7979

@@ -98,14 +98,14 @@ class MyTest extends TestCase
9898
}
9999
```
100100

101-
It's good practice to reset your database before each test so that data from a previous test does not interfere with your tests. The `RefreshDatabase` trait will help you wipe the database clean and run all migration up.
101+
It's good practice to reset your database before each test so that data from a previous test does not interfere with your tests. The `RefreshDatabase` trait will help you wipe the database clean and run all migrations up.
102102

103103
> [!WARNING]
104104
> This is **destructive**! All existing data in the database will be lost. Use it along the in-memory SQLite database to avoid losing data in your production database
105105
106106
## WithTestUser
107107

108-
This trait contains many useful methods for tests that require an actual user. To use any of the methods, you first need to add the `UserFrosting\Sprinkle\Account\Testing\WithTestUser` trait to your class. This trait add a single public method, `actAsUser`:
108+
This trait contains many useful methods for tests that require an actual user. To use any of the methods, you first need to add the `UserFrosting\Sprinkle\Account\Testing\WithTestUser` trait to your class. This trait adds a single method, `actAsUser`:
109109

110110
```php
111111
protected function actAsUser(
@@ -116,7 +116,7 @@ protected function actAsUser(
116116
)
117117
```
118118

119-
The method accept a UserInterface class. Optionally, you can use the `$isMaster` to force the user to be a master user (useful to bypass any permission checks!), pass roles to assign to this user (as an array of `RoleInterface`), or permissions (as an array of `PermissionInterface` or permissions slugs).
119+
The method accepts a UserInterface class. Optionally, you can use the `$isMaster` to force the user to be a master user (useful to bypass any permission checks!), pass roles to assign to this user (as an array of `RoleInterface`), or permissions (as an array of `PermissionInterface` or permissions slugs).
120120

121121
**Example: Create a user using Factories, and assign `test_permissions`**
122122
```php

0 commit comments

Comments
 (0)