Skip to content

Commit 9806cad

Browse files
committed
updated readme for 1.0
1 parent 5d3b1e2 commit 9806cad

File tree

4 files changed

+178
-82
lines changed

4 files changed

+178
-82
lines changed

CHANGELOG.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
## 1.0
44

55
* PHPUnit 6 support
6-
* Removed configuration section
7-
* Only properties marked with `@specify` annotation will be cloned in specify blocks.
8-
* Added `Codeception\Specify\ResultPrinter` to fix printing of nested examples.
6+
* **Removed configuration** section
7+
* **Only properties marked with `@specify` annotation are cloned** in specify blocks.
8+
* **Removed throws** parameter in specify blocks
9+
* Added `Codeception\Specify\ResultPrinter` to fix printing progress of specify blcoks.
910

1011
### Upgrade Plan
1112

1213
1. Update to PHP7+ PHPUnit 6+
13-
2. Add to `phpunit.xml`
14+
2. Add to `phpunit.xml`: `printerClass="Codeception\Specify\ResultPrinter"`
15+
3. If relied on property cloning, add `@specify` annotation for all properties which needs to be cloned for specify blocks
16+
4. If you used `throws` parameter, consider using [AssertThrows](https://github.com/Codeception/AssertThrows) package.
1417

1518
#### 0.4.3
1619

README.md

Lines changed: 126 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,69 @@ Specify
33

44
BDD style code blocks for PHPUnit / Codeception
55

6+
[![Latest Stable Version](https://poser.pugx.org/codeception/specify/v/stable)](https://packagist.org/packages/codeception/specify)[![Total Downloads](https://poser.pugx.org/codeception/specify/downloads)](https://packagist.org/packages/codeception/specify)[![Latest Unstable Version](https://poser.pugx.org/codeception/specify/v/unstable)](https://packagist.org/packages/codeception/specify)[![License](https://poser.pugx.org/codeception/specify/license)](https://packagist.org/packages/codeception/specify)
7+
68
Specify allows you to write your tests in more readable BDD style, the same way you might have experienced with [Jasmine](https://jasmine.github.io/).
79
Inspired by MiniTest of Ruby now you combine BDD and classical TDD style in one test.
810

9-
[![Build Status](https://travis-ci.org/Codeception/Specify.png?branch=master)](https://travis-ci.org/Codeception/Specify) [![Latest Stable Version](https://poser.pugx.org/codeception/specify/v/stable.png)](https://packagist.org/packages/codeception/specify)
11+
### BDD Example
1012

11-
Additionaly, we recommend to combine this with [**Codeception/Verify**](https://github.com/Codeception/Verify) library, to get BDD style assertions.
13+
Specify supports `describe-it` BDD syntax inside PHPUnit
1214

13-
``` php
15+
```php
1416
<?php
15-
class UserTest extends PHPUnit_Framework_TestCase {
17+
class UserTest extends PHPUnit\Framework\TestCase {
1618

1719
use Codeception\Specify;
20+
21+
/** @specify */
22+
protected $user;
23+
24+
public function setUp()
25+
{
26+
$this->user = new User;
27+
}
28+
29+
public function testValidation()
30+
{
31+
$this->describe("user", function() {
32+
$this->it("should have a name", function() {
33+
$this->user->username = null;
34+
$this->assertFalse($this->user->validate(['username']));
35+
});
36+
37+
$this->it("should not have long name", function() {
38+
$this->user->username = 'toolooooongnaaaaaaameeee';
39+
$this->assertFalse($this->user->validate(['username']));
40+
});
41+
42+
// use `$this->>should` as shortcut
43+
$this->should("be ok with valid name", function() {
44+
$this->user->username = 'davert';
45+
$this->assertTrue($this->user->validate(['username']));
46+
});
47+
48+
// empty codeblocks are marked as Incomplete tests
49+
$this->it("should be ok with valid name");
50+
});
51+
52+
}
53+
}
54+
```
55+
56+
### Basic Example
57+
58+
Traditionally Specify used `$this->specify` function for all descriptions.
59+
That works too!
60+
61+
```php
62+
<?php
63+
class UserTest extends PHPUnit\Framework\TestCase {
64+
65+
use Codeception\Specify;
66+
67+
/** @specify */
68+
protected $user;
1869

1970
public function setUp()
2071
{
@@ -27,32 +78,31 @@ class UserTest extends PHPUnit_Framework_TestCase {
2778

2879
$this->specify("username is required", function() {
2980
$this->user->username = null;
30-
verify($this->user->validate(['username'])->false());
81+
$this->assertFalse($this->user->validate(['username']));
3182
});
3283

3384
$this->specify("username is too long", function() {
3485
$this->user->username = 'toolooooongnaaaaaaameeee',
35-
verify($this->user->validate(['username'])->false());
86+
$this->assertFalse($this->user->validate(['username']));
3687
});
3788

38-
// alternative, TDD assertions can be used too.
3989
$this->specify("username is ok", function() {
4090
$this->user->username = 'davert',
4191
$this->assertTrue($this->user->validate(['username']));
4292
});
4393
}
4494
}
45-
?>
4695
```
4796

97+
4898
## Purpose
4999

50-
This tiny library makes your tests a bit readable, by orginizing test in well described code blocks.
100+
This tiny library makes your tests a bit readable, by organizing test in well described code blocks.
51101
Each code block is isolated.
52102

53-
This means call to `$this->specify` does not affect any instance variable of a test class.
103+
This means call to `$this->specify` does not change values of configured properties of a test class.
54104

55-
``` php
105+
```php
56106
<?php
57107
$this->user->name = 'davert';
58108
$this->specify("i can change my name", function() {
@@ -66,7 +116,7 @@ $this->assertEquals('davert', $this->user->name);
66116

67117
Failure in `specify` block won't get your test stopped.
68118

69-
``` php
119+
```php
70120
<?php
71121
$this->specify("failing but test goes on", function() {
72122
$this->fail('bye');
@@ -82,107 +132,92 @@ If a test fails you will see specification text in the result.
82132
## Isolation
83133

84134
Isolation is achieved by **cloning object properties** for each specify block.
85-
By default objects are cloned using deep cloning method.
86-
This behavior can be customized in order to speed up test execution by preventing some objects from cloning or switching to shallow cloning using `clone` operator.
87-
Some properties can be ignored from cloning using either global or local config settings.
88-
89-
### Global Configuration
90-
91-
Cloning configuration can be set globally
135+
Only properties makred with `@specify` annotation are cloned.
92136

93137
```php
94-
<?php
95-
// globally disabling cloning of properties
96-
Codeception\Specify\Config::setIgnoredProperties(['user', 'repository']);
97-
?>
98-
```
138+
/** @specify */
139+
protected $user; // cloning
99140

100-
See complete [reference](https://github.com/Codeception/Specify/blob/master/docs/GlobalConfig.md).
141+
/**
142+
* @specify
143+
**/
144+
protected $user; // cloning
101145

102-
### Local Configuration
146+
protected $repository; // not cloning
147+
```
103148

104-
Configuring can be done locally per test case
149+
Objects are cloned using deep cloning method.
150+
**If object cloning affects performance, consider turning the clonning off**.
105151

106-
```php
107-
<?php
108-
class UserTest extends \PHPUnit_Framework_TestCase
109-
{
110-
use Codeception\Specify;
111-
112-
function testUser()
113-
{
114-
// do not deep clone user property
115-
$this->specifyConfig()
116-
->shallowClone('user');
117-
}
118-
}
119-
```
152+
**Mocks are isolated** by default.
120153

121-
Only specific properties can be preserved in specify blocks:
154+
A mock defined inside a specify block won't be executed inside an outer test,
155+
and mock from outer test won't be triggered inside codeblock.
122156

123157
```php
124158
<?php
125-
class UserTest extends \PHPUnit_Framework_TestCase
126-
{
127-
use Codeception\Specify;
128-
protected $user;
129-
protected $post;
159+
$config = $this->createMock(Config::class);
160+
$config->expects($this->once())->method('init');
130161

131-
function testUser()
132-
{
133-
$this->user = 'davert';
134-
$this->post = 'hello world';
162+
$config->init();
163+
// success: $config->init() was executed
135164

136-
$this->specifyConfig()
137-
->cloneOnly('user');
165+
$this->specify('this should not fail', function () {
166+
$config = $this->createMock(Config::class);
167+
$config->expects($this->never())->method('init')->willReturn(null);
168+
// success: $config->init() is never executed
169+
});
138170

139-
$this->specify('post is not cloned', function() {
140-
$this->user = 'john';
141-
$this->post = 'bye world';
142-
});
143-
$this->assertEquals('davert', $this->user); // user is restored
144-
$this->assertEquals('bye world', $this->post); // post was not stored
145-
}
146-
}
147171
```
148172

149-
150-
[Reference](https://github.com/Codeception/Specify/blob/master/docs/LocalConfig.md)
151-
152-
153-
## Exceptions
154-
155-
156173
## Examples
157174

158-
DataProviders alternative. Quite useful for basic data providers.
175+
DataProviders alternative
159176

160-
``` php
177+
```php
161178
<?php
162179
$this->specify("should calculate square numbers", function($number, $square) {
163180
$this->assertEquals($square, $number*$number);
164181
}, ['examples' => [
165182
[2,4],
166183
[3,9]
167184
]]);
168-
?>
169185
```
170186

171187
You can also use DataProvider functions in `examples` param.
172188

173-
``` php
189+
```php
174190
<?php
175191
$this->specify("should calculate square numbers", function($number, $square) {
176192
$this->assertEquals($square, $number*$number);
177193
}, ['examples' => $this->provider()]);
178-
?>
194+
```
195+
196+
Can also be used with real data providers:
197+
198+
```php
199+
<?php
200+
/**
201+
* @dataProvider someData
202+
*/
203+
public function testExamplesAndDataProvider($param)
204+
{
205+
$this->specify('should assert data provider', function ($example) use ($param) {
206+
$this->assertGreaterThanOrEqual(5, $param + $example);
207+
}, ['examples' => [[4], [7], [5]]]);
208+
}
209+
210+
public function someData()
211+
{
212+
return [[1], [2]];
213+
}
179214
```
180215

181216
## Before/After
182217

183218
There are also before and after callbacks, which act as setUp/tearDown but only for specify.
184219

185-
``` php
220+
```php
186221
<?php
187222
$this->beforeSpecify(function() {
188223
// prepare something;
@@ -194,9 +229,19 @@ $this->cleanSpecify(); // removes before/after callbacks
194229
?>
195230
```
196231

232+
## API
233+
234+
Available methods:
235+
236+
* `$this->specify(name, callable fn = null, params = [])` - starts a specify code block. If `fn` is null, marks test as incomplete.
237+
* `$this->describe(name, callable fn = null)` - starts a describe code block. Same as `specify` but expects to receive more nested into `fn`.
238+
* `$this->it(name, callable fn = null)` - starts a code block. Alias to `specify`.
239+
* `$this->should(name, callable fn = null)` - starts a code block. Same as `specify` but prepends word "should" into description.
240+
241+
197242
## Installation
198243

199-
*Requires PHP >= 5.4.*
244+
*Requires PHP >= 7.*
200245

201246
Install with Composer:
202247

@@ -208,7 +253,12 @@ Install with Composer:
208253

209254
}
210255
```
211-
Include `Codeception\Specify` trait into your test.
256+
Include `Codeception\Specify` trait into `PHPUnit\Framework\TestCase`.
257+
258+
## Recommended
212259

260+
* Use [Codeception/AssertThrows](https://github.com/Codeception/AssertThrows) for exception assertions
261+
* Use [Codeceptoin/DomainAssert](https://github.com/Codeception/DomainAssert) for verbose domain logic assertions
262+
* Сombine this with [Codeception/Verify](https://github.com/Codeception/Verify) library, to get BDD style assertions.
213263

214264
License: MIT

src/Codeception/Specify.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function should($specification, \Closure $callable = null, $params = [])
3838

3939
public function it($specification, \Closure $callable = null, $params = [])
4040
{
41-
$this->specify("should " . $specification, $callable, $params);
41+
$this->specify($specification, $callable, $params);
4242
}
4343

4444
public function describe($specification, \Closure $callable = null)

0 commit comments

Comments
 (0)