@@ -10,42 +10,27 @@ Inspired by MiniTest of Ruby now you combine BDD and classical TDD style in one
1010
1111### Basic Example
1212
13- Traditionally Specify used ` $this->specify ` function for all descriptions.
14- That works too!
13+ Specify ` $this->specify ` method to add isolated test blocks for your PHPUnit tests!
1514
1615``` php
17- <?php
18- class UserTest extends PHPUnit\Framework\TestCase {
19-
20- use Codeception\Specify;
21-
22- /** @specify */
23- protected $user;
24-
25- public function setUp()
26- {
27- $this->user = new User;
28- }
29-
30- public function testValidation()
31- {
32- $this->assertInstanceOf('Model', $this->user);
33-
34- $this->specify("username is required", function() {
35- $this->user->username = null;
36- $this->assertFalse($this->user->validate(['username']));
37- });
38-
39- $this->specify("username is too long", function() {
40- $this->user->username = 'toolooooongnaaaaaaameeee',
41- $this->assertFalse($this->user->validate(['username']));
42- });
43-
44- $this->specify("username is ok", function() {
45- $this->user->username = 'davert',
46- $this->assertTrue($this->user->validate(['username']));
47- });
48- }
16+ public function testValidation()
17+ {
18+ $this->assertInstanceOf('Model', $this->user);
19+
20+ $this->specify("username is required", function() {
21+ $this->user->username = null;
22+ $this->assertFalse($this->user->validate(['username']));
23+ });
24+
25+ $this->specify("username is too long", function() {
26+ $this->user->username = 'toolooooongnaaaaaaameeee';
27+ $this->assertFalse($this->user->validate(['username']));
28+ });
29+
30+ $this->specify("username is ok", function() {
31+ $this->user->username = 'davert';
32+ $this->assertTrue($this->user->validate(['username']));
33+ });
4934}
5035```
5136
@@ -54,43 +39,28 @@ class UserTest extends PHPUnit\Framework\TestCase {
5439Specify supports ` describe-it ` BDD syntax inside PHPUnit
5540
5641``` php
57- <?php
58- class UserTest extends PHPUnit\Framework\TestCase {
59-
60- use Codeception\Specify;
61-
62- /** @specify */
63- protected $user;
64-
65- public function setUp()
66- {
67- $this->user = new User;
68- }
69-
70- public function testValidation()
71- {
72- $this->describe("user", function() {
73- $this->it("should have a name", function() {
74- $this->user->username = null;
75- $this->assertFalse($this->user->validate(['username']));
76- });
77-
78- $this->it("should not have long name", function() {
79- $this->user->username = 'toolooooongnaaaaaaameeee';
80- $this->assertFalse($this->user->validate(['username']));
81- });
82-
83- // use `$this->>should` as shortcut
84- $this->should("be ok with valid name", function() {
85- $this->user->username = 'davert';
86- $this->assertTrue($this->user->validate(['username']));
87- });
88-
89- // empty codeblocks are marked as Incomplete tests
90- $this->it("should be ok with valid name");
42+ public function testValidation()
43+ {
44+ $this->describe("user", function() {
45+ $this->it("should have a name", function() {
46+ $this->user->username = null;
47+ $this->assertFalse($this->user->validate(['username']));
9148 });
9249
93- }
50+ $this->it("should not have long name", function() {
51+ $this->user->username = 'toolooooongnaaaaaaameeee';
52+ $this->assertFalse($this->user->validate(['username']));
53+ });
54+
55+ // use `$this->>should` as shortcut
56+ $this->should("be ok with valid name", function() {
57+ $this->user->username = 'davert';
58+ $this->assertTrue($this->user->validate(['username']));
59+ });
60+
61+ // empty codeblocks are marked as Incomplete tests
62+ $this->it("should be ok with valid name");
63+ });
9464}
9565```
9666
@@ -100,40 +70,58 @@ class UserTest extends PHPUnit\Framework\TestCase {
10070Use [ Codeception/Verify] ( https://github.com/Codeception/Verify ) for simpler assertions:
10171
10272``` php
103- <?php
104- $this->specify("username is required", function() {
105- $this->user->username = null;
106- expect_not($this->user->validate(['username']));
107- });
108-
109- $this->specify("username is too long", function() {
110- $this->user->username = 'toolooooongnaaaaaaameeee';
111- expect_not($this->user->validate(['username']));
112- });
113-
114- $this->specify("username is ok", function() {
115- $this->user->username = 'davert';
116- expect_that($this->user->validate(['username']));
117- });
73+ public function testValidation()
74+ {
75+ $this->specify("username is required", function() {
76+ $this->user->username = null;
77+ expect_not($this->user->validate(['username']));
78+ });
79+
80+ $this->specify("username is too long", function() {
81+ $this->user->username = 'toolooooongnaaaaaaameeee';
82+ expect_not($this->user->validate(['username']));
83+ });
84+
85+ $this->specify("username is ok", function() {
86+ $this->user->username = 'davert';
87+ expect_that($this->user->validate(['username']));
88+ });
89+ }
11890```
11991
12092## Purpose
12193
12294This tiny library makes your tests a bit readable, by organizing test in well described code blocks.
12395Each code block is isolated.
12496
125- This means call to ` $this->specify ` does not change values of configured properties of a test class.
97+ This means call to ` $this->specify ` does not change values of properties of a test class.
98+ Isolated properties should be marked with ` @specify ` annotation.
12699
127100``` php
128101<?php
129- $this->user->name = 'davert';
130- $this->specify("i can change my name", function() {
131- $this->user->name = 'jon';
132- $this->assertEquals('jon', $this->user->name);
133- });
134-
135- $this->assertEquals('davert', $this->user->name);
136- ?>
102+ class UserTest extends PHPUnit\Framework\TestCase {
103+
104+ use Codeception\Specify;
105+
106+ /** @specify */
107+ protected $user; // is cloned inside specify blocks
108+
109+ public function setUp()
110+ {
111+ $this->user = new User;
112+ }
113+
114+ public function testValidation()
115+ {
116+ $this->user->name = 'davert';
117+ $this->specify("i can change my name", function() {
118+ $this->user->name = 'jon';
119+ $this->assertEquals('jon', $this->user->name);
120+ });
121+ // user name is davert again
122+ $this->assertEquals('davert', $this->user->name);
123+ }
124+ }
137125```
138126
139127Failure in ` specify ` block won't get your test stopped.
@@ -154,7 +142,7 @@ If a test fails you will see specification text in the result.
154142## Isolation
155143
156144Isolation is achieved by ** cloning object properties** for each specify block.
157- Only properties makred with ` @specify ` annotation are cloned.
145+ Only properties marked with ` @specify ` annotation are cloned.
158146
159147``` php
160148/** @specify */
@@ -169,6 +157,7 @@ protected $repository; // not cloning
169157```
170158
171159Objects are cloned using deep cloning method.
160+
172161** If object cloning affects performance, consider turning the clonning off** .
173162
174163** Mocks are isolated** by default.
@@ -189,7 +178,6 @@ $this->specify('this should not fail', function () {
189178 $config->expects($this->never())->method('init')->willReturn(null);
190179 // success: $config->init() is never executed
191180});
192-
193181```
194182
195183## Examples
@@ -265,19 +253,16 @@ Available methods:
265253
266254* Requires PHP >= 7.*
267255
268- Install with Composer:
269-
256+ * Install with Composer:
270257
271- ``` json
272- "require-dev" : {
273- "codeception/specify" : " *" ,
274- "codeception/verify" : " *"
275- }
276258```
277- Include ` Codeception\Specify ` trait into ` PHPUnit\Framework\TestCase ` .
259+ composer require codeception/specify --dev
260+ ```
278261
279- For PHPUnit add ` Codeception\Specify\ResultPrinter ` printer into ` phpunit.xml `
262+ * Include ` Codeception\Specify ` trait into ` PHPUnit\Framework\TestCase ` .
263+ * Add ` /** @specify **/ ` docblock for all properties you want to make isolated inside tests.
280264
265+ * For PHPUnit add ` Codeception\Specify\ResultPrinter ` printer into ` phpunit.xml `
281266
282267``` xml
283268<phpunit colors =" true" printerClass =" Codeception\Specify\ResultPrinter" >
0 commit comments