|
| 1 | +Tests |
| 2 | +===== |
| 3 | + |
| 4 | +Roughly speaking, there are two types of test. Unit testing allows you to |
| 5 | +test the input and output of specific functions. Functional testing allows |
| 6 | +you to command a "browser" where you browse to pages on your site, click |
| 7 | +links, fill out forms and assert that you see certain things on the page. |
| 8 | + |
| 9 | +Unit Tests |
| 10 | +---------- |
| 11 | + |
| 12 | +Unit tests are used to test your "business logic", which should live in classes |
| 13 | +that are independent of Symfony. For that reason, Symfony doesn't really |
| 14 | +have an opinion on what tools you use for unit testing. However, the most |
| 15 | +popular tools are `PhpUnit`_ and `PhpSpec`_. |
| 16 | + |
| 17 | +Functional Tests |
| 18 | +---------------- |
| 19 | + |
| 20 | +Creating really good functional tests can be tough so some developers skip |
| 21 | +these completely. Don't skip the functional tests! By defining some *simple* |
| 22 | +functional tests, you can quickly spot any big errors before you deploy them: |
| 23 | + |
| 24 | +.. best-practice:: |
| 25 | + |
| 26 | + Define a functional test that at least checks if your application pages |
| 27 | + are successfully loading. |
| 28 | + |
| 29 | +A functional test can be as easy as this: |
| 30 | + |
| 31 | +.. code-block:: php |
| 32 | +
|
| 33 | + /** @dataProvider provideUrls */ |
| 34 | + public function testPageIsSuccessful($url) |
| 35 | + { |
| 36 | + $client = self::createClient(); |
| 37 | + $client->request('GET', $url); |
| 38 | +
|
| 39 | + $this->assertTrue($client->getResponse()->isSuccessful()); |
| 40 | + } |
| 41 | +
|
| 42 | + public function provideUrls() |
| 43 | + { |
| 44 | + return array( |
| 45 | + array('/'), |
| 46 | + array('/posts'), |
| 47 | + array('/post/fixture-post-1'), |
| 48 | + array('/blog/category/fixture-category'), |
| 49 | + array('/archives'), |
| 50 | + // ... |
| 51 | + ); |
| 52 | + } |
| 53 | +
|
| 54 | +This code checks that all the given URLs load successfully, which means that |
| 55 | +their HTTP response status code is between ``200`` and ``299``. This may |
| 56 | +not look that useful, but given how little effort this took, it's worth |
| 57 | +having it in your application. |
| 58 | + |
| 59 | +In computer software, this kind of test is called `smoke testing`_ and consists |
| 60 | +of *"preliminary testing to reveal simple failures severe enough to reject a |
| 61 | +prospective software release"*. |
| 62 | + |
| 63 | +Hardcode URLs in a Functional Test |
| 64 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 65 | + |
| 66 | +Some of you may be asking why the previous functional test doesn't use the URL |
| 67 | +generator service: |
| 68 | + |
| 69 | +.. best-practice:: |
| 70 | + |
| 71 | + Hardcode the URLs used in the functional tests instead of using the URL |
| 72 | + generator. |
| 73 | + |
| 74 | +Consider the following functional test that uses the ``router`` service to |
| 75 | +generate the URL of the tested page: |
| 76 | + |
| 77 | +.. code-block:: php |
| 78 | +
|
| 79 | + public function testBlogArchives() |
| 80 | + { |
| 81 | + $client = self::createClient(); |
| 82 | + $url = $client->getContainer()->get('router')->generate('blog_archives'); |
| 83 | + $client->request('GET', $url); |
| 84 | +
|
| 85 | + // ... |
| 86 | + } |
| 87 | +
|
| 88 | +This will work, but it has one *huge* drawback. If a developer mistakenly |
| 89 | +changes the path of the ``blog_archives`` route, the test will still pass, |
| 90 | +but the original (old) URL won't work! This means that any bookmarks for |
| 91 | +that URL will be broken and you'll lose any search engine page ranking. |
| 92 | + |
| 93 | +Testing JavaScript Functionality |
| 94 | +-------------------------------- |
| 95 | + |
| 96 | +The built-in functional testing client is great, but it can't be used to |
| 97 | +test any JavaScript behavior on your pages. If you need to test this, consider |
| 98 | +using the `Mink`_ library from within PHPUnit. |
| 99 | + |
| 100 | +Of course, if you have a heavy JavaScript frontend, you should consider using |
| 101 | +pure JavaScript-based testing tools. |
| 102 | + |
| 103 | +Learn More about Functional Tests |
| 104 | +--------------------------------- |
| 105 | + |
| 106 | +Consider using `Faker`_ and `Alice`_ libraries to generate real-looking data |
| 107 | +for your test fixtures. |
| 108 | + |
| 109 | +.. _`Faker`: https://github.com/fzaninotto/Faker |
| 110 | +.. _`Alice`: https://github.com/nelmio/alice |
| 111 | +.. _`PhpUnit`: https://phpunit.de/ |
| 112 | +.. _`PhpSpec`: http://www.phpspec.net/ |
| 113 | +.. _`Mink`: http://mink.behat.org |
| 114 | +.. _`smoke testing`: http://en.wikipedia.org/wiki/Smoke_testing_(software) |
0 commit comments