Skip to content

Commit 5d11fc8

Browse files
committed
Enhance "Introduction" pages in docs
1 parent b7fd22e commit 5d11fc8

11 files changed

Lines changed: 384 additions & 257 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ llms_description: "Technical description of what LLM learns from this page"
103103

104104
**Guidelines for `llms_description`:**
105105
- List specific classes, attributes, methods — not vague descriptions
106-
- Example: `"#[BeforeEach], #[AfterEach], #[BeforeAll], #[AfterAll] lifecycle hooks, execution order, priority"`
106+
- Example: `"#[BeforeTest], #[AfterTest], #[BeforeClass], #[AfterClass] lifecycle hooks, execution order, priority"`
107107
- NOT: `"Learn about test lifecycle management"`
108108

109109
**When adding new doc pages:** add `llms_description` to the English version frontmatter. Do NOT add llms frontmatter to blog posts.

docs/getting-started.md

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,33 +71,7 @@ final class MyFirstTest
7171
}
7272
```
7373

74-
The `#[Test]` attribute marks the method as a test, and the `Assert` facade checks assertions.
75-
Testo supports a wide range of assertions via `Assert` and expectations via `Expect`.
76-
77-
Use attributes to extend test functionality.
78-
For example, `#[Retry]` retries a test on failure, and `#[ExpectException]` expects a specific exception:
79-
80-
```php
81-
#[Test]
82-
final class MyFirstTest
83-
{
84-
#[Retry(maxAttempts: 5)] // Retries up to 5 times if test fails
85-
public function flakyTest(): void
86-
{
87-
Assert::same(mt_rand(0, 2), 2);
88-
}
89-
90-
#[ExpectException(\RuntimeException::class)]
91-
public function throwsException(): never
92-
{
93-
throw new \RuntimeException('Expected error');
94-
}
95-
}
96-
```
97-
98-
::: question Why `#[Test]` on a class?
99-
You can put `#[Test]` on a class — then all public methods with return type `void` or `never` become tests.
100-
:::
74+
The `#[Test]` attribute marks the method as a test, and the `Assert` facade checks assertions. More about test approaches, attributes, and conventions — in [Writing Tests](writing-tests.md).
10175

10276
## Running Tests
10377

docs/plugins/lifecycle.md

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
llms_description: "#[BeforeEach], #[AfterEach], #[BeforeAll], #[AfterAll] lifecycle hooks, execution order, priority, class instantiation behavior"
2+
llms_description: "#[BeforeTest], #[AfterTest], #[BeforeClass], #[AfterClass] lifecycle hooks, execution order, priority, class instantiation behavior"
33
---
44

55
# Lifecycle
@@ -51,25 +51,25 @@ To control state between tests, use lifecycle attributes described below.
5151

5252
## Attributes
5353

54-
| Attribute | When it runs | How often |
55-
|-----------|--------------|-----------|
56-
| `#[BeforeEach]` | Before each test method | Once per test |
57-
| `#[AfterEach]` | After each test method | Once per test |
58-
| `#[BeforeAll]` | Before all tests in the class | Once per test case |
59-
| `#[AfterAll]` | After all tests in the class | Once per test case |
54+
| Attribute | When it runs | How often |
55+
|------------------|-------------------------------|--------------------|
56+
| `#[BeforeTest]` | Before each test method | Once per test |
57+
| `#[AfterTest]` | After each test method | Once per test |
58+
| `#[BeforeClass]` | Before all tests in the class | Once per test case |
59+
| `#[AfterClass]` | After all tests in the class | Once per test case |
6060

6161
## Execution Order
6262

6363
```
64-
BeforeAll (once)
65-
├── BeforeEach
64+
BeforeClass (once)
65+
├── BeforeTest
6666
│ └── Test 1
67-
│ └── AfterEach
68-
├── BeforeEach
67+
│ └── AfterTest
68+
├── BeforeTest
6969
│ └── Test 2
70-
│ └── AfterEach
70+
│ └── AfterTest
7171
└── ...
72-
AfterAll (once)
72+
AfterClass (once)
7373
```
7474

7575
## Basic Example
@@ -80,25 +80,25 @@ final class DatabaseTest
8080
private static Connection $connection;
8181
private Transaction $transaction;
8282

83-
#[BeforeAll]
83+
#[BeforeClass]
8484
public static function connect(): void
8585
{
8686
self::$connection = new Connection();
8787
}
8888

89-
#[AfterAll]
89+
#[AfterClass]
9090
public static function disconnect(): void
9191
{
9292
self::$connection->close();
9393
}
9494

95-
#[BeforeEach]
95+
#[BeforeTest]
9696
public function beginTransaction(): void
9797
{
9898
$this->transaction = self::$connection->beginTransaction();
9999
}
100100

101-
#[AfterEach]
101+
#[AfterTest]
102102
public function rollback(): void
103103
{
104104
$this->transaction->rollback();
@@ -118,30 +118,23 @@ final class DatabaseTest
118118
When you have multiple methods with the same lifecycle attribute, use `priority` to control execution order:
119119

120120
```php
121-
#[BeforeEach(priority: 100)]
121+
#[BeforeTest(priority: 100)]
122122
public function initializeConfig(): void
123123
{
124124
// Runs first (highest priority)
125125
}
126126

127-
#[BeforeEach(priority: 50)]
127+
#[BeforeTest(priority: 50)]
128128
public function initializeLogger(): void
129129
{
130130
// Runs second
131131
}
132132

133-
#[BeforeEach] // priority: 0 (default)
133+
#[BeforeTest] // priority: 0 (default)
134134
public function initializeService(): void
135135
{
136136
// Runs last
137137
}
138138
```
139139

140140
Higher values execute first. Default priority is `0`.
141-
142-
## Error Handling
143-
144-
- Exception in `BeforeEach` — test is aborted
145-
- Exception in `AfterEach` — captured, but test result is preserved
146-
- Exception in `BeforeAll` — all tests in the class are aborted
147-
- Exception in `AfterAll` — captured after all tests complete

docs/plugins/test.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,44 @@ The `#[Test]` attribute explicitly marks a method, function, or class as a test.
88

99
Can be placed on:
1010

11-
- **Class** — all public methods with `void` return type become tests
11+
- **Class** — all public methods with `void` or `never` return type become tests
1212
- **Method** — only that method is a test
1313
- **Function** — the function is a test
1414

15-
```php
15+
::: code-group
16+
```php [#[Test] on class]
17+
// tests/Unit/Order.php
1618
#[Test]
17-
final class OrderTest
19+
final class Order
1820
{
1921
public function createsOrder(): void { /* ... */ }
2022

2123
public function calculatesTotal(): void { /* ... */ }
22-
23-
public function appliesDiscount(): void { /* ... */ }
2424
}
25-
26-
final class UserTest
25+
```
26+
```php [#[Test] on method]
27+
// tests/Unit/Order.php
28+
final class Order
2729
{
2830
#[Test]
29-
public function validatesEmail(): void { /* ... */ }
31+
public function createsOrder(): void { /* ... */ }
3032

3133
#[Test]
32-
public function checksPermissions(): void { /* ... */ }
34+
public function calculatesTotal(): void { /* ... */ }
3335
}
36+
```
37+
```php [Function]
38+
// tests/Unit/order.php
39+
#[Test]
40+
function creates_order(): void { /* ... */ }
41+
42+
#[Test]
43+
function calculates_total(): void { /* ... */ }
3444

3545
#[Test]
36-
function checks_environment(): void { /* ... */ }
46+
function applies_discount(): void { /* ... */ }
3747
```
48+
:::
3849

3950
## When to Use
4051

docs/why-testo.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Testo was born from the need for an extensible testing framework that could adap
2121

2222
## Testo Philosophy
2323

24-
### Developer's Full Control
24+
### Full Control for the Developer
2525

2626
From Testo's perspective, **tests are the developer's property, not the framework's**. All metadata and operational data needed by the framework are stored and processed separately.
2727

@@ -43,18 +43,19 @@ function simpleTest(): void
4343

4444
Testo is built on a simple idea: **a small core with a set of DTOs and contracts, and all functionality is built on top of middleware and event system**.
4545

46-
The core simply builds several pipelines from middleware, and then do whatever you want. Every framework feature is middleware or event handlers:
46+
The core simply builds several pipelines from middleware, and then do whatever you want. Every framework feature is middleware or event handlers, packaged into a plugin:
4747
- Attributes in general
4848
- Data providers
4949
- Inline testing
5050
- Assertion system (`Assert`, `Expect`)
5151
- CLI rendering and TeamCity
52+
- ...
5253

5354
### Well-Designed API
5455

55-
Instead of a bloated `Assert` facade with ~2300 lines (as in PHPUnit), Testo provides:
56-
- **`Assert`** — for assertions (checked here and now)
57-
- **`Expect`** — for expectations (checked after test completion)
56+
Instead of a bloated `Assert` facade, Testo provides:
57+
- **`Assert`** — for assertions (checked here and now).
58+
- **`Expect`** — for expectations (checked after test completion).
5859
- **Pipe assertions** — grouping by types for cleaner code:
5960

6061
```php
@@ -74,12 +75,15 @@ Testo comes with a [PhpStorm/IntelliJ IDEA plugin](https://plugins.jetbrains.com
7475

7576
## Who Is Testo For?
7677

77-
Testo is built for those who:
78-
- Develop **frameworks** and need deep test integration.
79-
- Create **SDKs** with specific testing requirements.
80-
- Build **complex systems** where PHPUnit doesn't provide the needed flexibility.
81-
- Want **full control** over testing infrastructure.
82-
- Prefer PHP syntax over JS.
78+
Testo is for anyone who loves PHP.
79+
80+
Open-source developers can count on support for [current PHP versions](https://www.php.net/supported-versions.php).
81+
Framework and SDK authors get a powerful tool for building their own test environments through Testo integration.
82+
83+
Developers on projects get clean tests without needing to learn new syntactic constructs or concepts.
84+
Flexible settings and the plugin system allow adapting Testo to any project requirements, from simple unit tests to complex integration scenarios.
85+
86+
After all, I'm a framework, SDK, and high-load project developer myself, so I know all these pains firsthand.
8387

8488
## What's Next?
8589

0 commit comments

Comments
 (0)