|
| 1 | +--- |
| 2 | +title: Testing Symnfony2 with Codeception |
| 3 | +layout: post |
| 4 | +date: 2013-02-12 01:03:50 |
| 5 | +--- |
| 6 | + |
| 7 | +From the beginning of it's existence Codeception was in good relations with Symfony2 framework. Codeception was built on Symfony Components and uses BrowserKit and HttpKernel components for launching funcational tests. It's a shame we didn't have a complete Symfony2 integration tutorial before. But we will try to fill this gap today. |
| 8 | + |
| 9 | +What benefits you get by using Codeception with Symfony2? |
| 10 | +Let's list all of them: |
| 11 | + |
| 12 | +* user-friendly syntax for functional tests |
| 13 | +* access to container in unit tests |
| 14 | +* testing REST and SOAP services built on Symfony |
| 15 | +* fastest data cleanup when using with Doctrine2 |
| 16 | + |
| 17 | +The installation is pretty simple. You can use [Composer](http://codeception.com/install) (as you are used to it), but we'd recommend to try [phar package](http://codeception.com/thanks). In this case you can avoid unnecessary dependencies. But all this versions are equal. And when you installed Codeception and executed a `bootstrap` command you should configure your functional test suite. |
| 18 | + |
| 19 | +In file `tests/functional.suite.yml`: |
| 20 | + |
| 21 | +{% highlight yaml %} |
| 22 | +class_name: TestGuy |
| 23 | +modules: |
| 24 | + enabled: [Symfony2, Doctrine2, TestHelper] |
| 25 | +{% endhighlight %} |
| 26 | + |
| 27 | +And nothing more. You just need to declare that you will be using Symfony2 and Doctrine2. The Symfony2 module will search for `AppKrenel` on initialization (in `app`) and use it for functional tests. Doctrine2 module will find that Symfony2 module is declared and will try to receive default database connection from container. Of cource, If you use non-standard setup this behavior can be reconfigured. |
| 28 | + |
| 29 | +## Functional Testing |
| 30 | + |
| 31 | +Let's create a first functional test. We use `generate:cept functional TestName` command. |
| 32 | + |
| 33 | +{% highlight php %} |
| 34 | +<?php |
| 35 | +$I = new TestGuy($scenario); |
| 36 | +$I->wantTo('log in to site'); |
| 37 | +$I->amOnPage('/'); |
| 38 | +$I->click('Login'); |
| 39 | +$I->fillField('username', 'admin'); |
| 40 | +// .... |
| 41 | +?> |
| 42 | +{% endhighlight %} |
| 43 | + |
| 44 | +And so on. Unlike standard Symfony2 tests you don't need to deal with filters, CSS, and XPaths. Well, you can use CSS or XPath in any selector, if you need to. But on start you can kepp your test simple and compact. |
| 45 | + |
| 46 | +The commands we use here are common for most modules that perform testing of web application. That means, that once you discover a need for Selenium, this test can be executed inside a web browser useing Selenium2 module. But some commands are unique to Symfony2 module. For example, you can use `seeEmailIsSent` command that checks if application has submitted an email during the last request. Check [Symfony2](http://codeception.com/docs/modules/Symfony2) module reference for all commands we provide. |
| 47 | + |
| 48 | +## Unit Testing |
| 49 | + |
| 50 | +Codeception's unit tests are a bit improved PHPUnit's tests. Inside a unit tests you have access to initialized modules and guy classes. |
| 51 | + |
| 52 | +{% highlight php %} |
| 53 | +<?php |
| 54 | +class PaginateTest extends \Codeception\TestCase\Test |
| 55 | +{ |
| 56 | + private $serviceContainer; |
| 57 | + protected $codeGuy; |
| 58 | +
|
| 59 | + protected function _before() |
| 60 | + { |
| 61 | + // accessing container |
| 62 | + $this->serviceContainer = $this->getModule('Symfony2')->container; |
| 63 | + $this->serviceContainer->enterScope('request'); |
| 64 | + } |
| 65 | + |
| 66 | + public function testDefaults() |
| 67 | + { |
| 68 | + // using container |
| 69 | + $this->serviceContainer->set('request', new Request(), 'request'); |
| 70 | + $paginate = new Paginate($this->getModule('Symfony2')->container); |
| 71 | + $this->assertEquals(1, $paginate->getCurrentPage()); |
| 72 | + $this->assertEquals(0, $paginate->getCount()); |
| 73 | + $this->assertEquals(20, $paginate->getLimit()); |
| 74 | + |
| 75 | + // checking data in repository |
| 76 | + $this->codeGuy->seeInRepository('SettingsBundle:Settings', ['pager_limit' => 20]); |
| 77 | + } |
| 78 | +} |
| 79 | +?> |
| 80 | +{% endhighlight %} |
| 81 | + |
| 82 | +If you want to bypass Codeception hooks for PHPUnit you can create a plain PHPUnit test with `generate:phpunit` command and get a traiditional PHPUnit's test. |
| 83 | +Then you can put this test into bundle. |
| 84 | + |
| 85 | +## Conclusion |
| 86 | + |
| 87 | +Ok, you will probably ask: why is it better then Behat. We have a [wide answer for that](http://codeception.com/12-20-2012/not-bdd.html). A short is: Codeception is for testing, Behat is for Behavior Driven Development. If you need a professional testing tool that supports [PageObject](http://codeception.com/10-30-2012/pro-tips-1.html) pattern, complex [Locators](http://codeception.com/09-24-2012/locator.html), better refactoring capabilities and [CodeCoverage](http://codeception.com/docs/11-Codecoverage) - Codeception is a good choice. |
| 88 | + |
| 89 | +We say thanks to @everzet for wonderful Mink (that is used for acceptance tests) and to Sebastian Bergmann for it's PHPUnit. Codeception uses their powers, but makes them a bit simpler in use. |
0 commit comments