diff --git a/jobeet/pt_BR/09.markdown b/jobeet/pt_BR/09.markdown
new file mode 100644
index 0000000..12d874b
--- /dev/null
+++ b/jobeet/pt_BR/09.markdown
@@ -0,0 +1,737 @@
+Dia 9: Os Testes Funcionais
+===========================
+
+Ontem nós vimos como testar unitariamente nossas classes do Jobeet usando a
+biblioteca lime que vem embutida no symfony. Hoje, iremos escrever testes
+funcionais para as funcionalidades que já implementamos nos módulos `job` e
+`category`.
+
+Testes Funcionais
+-----------------
+
+Os testes funcionais são uma excelente ferramenta para testar sua aplicação de
+ponta a ponta: desde a requisição feita pelo navegador até a resposta enviada
+pelo servidor. Eles testam todas as camadas da aplicação: as rotas, os models,
+as actions e os templates. Eles se parecem bastante com o que você
+provavelmente já faz manualmente: toda vez que você adiciona ou modifica uma
+action, você precisa ir no navegador e verificar se tudo funciona como o
+esperado clicando nos links e verificando os elementos na página renderizada.
+Em outras palavras, você roda um cenário correspondente ao caso de uso que
+você acabou de implementar.
+
+Como o processo é manual, ele é tedioso e sujeito a erros. Cada vez que você
+muda algo no código, você precisa percorrer todos os cenários para garantir
+que o que você fez não quebrou nada. Isso é insano. Os testes funcionais no
+symfony fornecem uma maneira fácil de descrever cenários. Cada um dos
+cenários pode ser rodado automaticamente várias vezes simulando a experiência
+de um usuário no navegador. Assim como os testes unitários, eles te dão
+confiança para codificar em paz.
+
+>**NOTE**
+>O framework de testes funcionais não substitui ferramentas como o
+>"[~Selenium~](http://selenium.seleniumhq.org/)". O Selenium roda diretamente
+>no navegador para automatizar testes através de várias plataformas e
+>navegadores, além de poder testar o JavaScript da aplicação.
+
+A classe `sfBrowser`
+--------------------
+
+No symfony, os testes funcionais são executados através de um navegador
+especial implementado pela classe
+[~`sfBrowser`|Browser~](http://www.symfony-project.org/api/1_4/sfBrowser).
+Ele age como um navegador adaptado para sua aplicação que fica conectado
+diretamente nele, sem a necessidade de um servidor web. Ele te dá acesso a
+todos os objetos do symfony antes e depois de cada requisição, dando a
+oportunidade de analisá-los e verificá-los programaticamente.
+
+`sfBrowser` fornece métodos que simulam a navegação feita em um navegador
+clássico:
+
+ | Método | Descrição
+ | ------------ | ------------------------------------------------------
+ | `get()` | Faz uma requisição GET em uma URL
+ | `post()` | Faz uma requisição POST em uma URL
+ | `call()` | Chama uma URL (usado para os métodos `PUT` e `DELETE`)
+ | `back()` | Volta uma página no histórico
+ | `forward()` | Avança uma página no histórico
+ | `reload()` | Recarrega a página atual
+ | `click()` | Clica em um link ou botão
+ | `select()` | Seleciona um radiobutton ou checkbox
+ | `deselect()` | Desmarca um radiobutton ou checkbox
+ | `restart()` | Reinicia o navegador
+
+Aqui estão alguns exemplos de uso dos métodos de `sfBrowser`:
+
+ [php]
+ $browser = new sfBrowser();
+
+ $browser->
+ get('/')->
+ click('Design')->
+ get('/category/programming?page=2')->
+ get('/category/programming', array('page' => 2))->
+ post('search', array('keywords' => 'php'))
+ ;
+
+`sfBrowser` contém métodos adicionais para configurar o comportamento do
+navegador:
+
+ | Método | Descrição
+ | ------------------ | -------------------------------------------------
+ | `setHttpHeader()` | Define um cabeçalho HTTP
+ | `setAuth()` | Define credenciais de autenticação básica
+ | `setCookie()` | Define um cookie
+ | `removeCookie()` | Remove um cookie
+ | `clearCookies()` | Limpa todos os cookies atuais
+ | `followRedirect()` | Segue um redirecionamento
+
+A classe `sfTestFunctional`
+---------------------------
+
+Nós temos um navegador, mas precisamos de uma maneira de verificar
+internamente os objetos do symfony para fazer os testes de verdade. Isso poderia
+ser feito com o lime e alguns métodos de `sfBrowser` como `getResponse()` e
+`getRequest()`, mas o symfony fornece uma maneira melhor.
+
+Os métodos de teste são fornecidos por outra classe,
+[`sfTestFunctional`](http://www.symfony-project.org/api/1_4/sfTestFunctional),
+que recebe uma instância de `sfBrowser` em seu construtor. A classe
+`sfTestFunctional` delega os os testes para objetos testadores. Muitos
+testadores são embutidos no symfony, e você também pode criar os seus
+próprios.
+
+Como vimos no dia 8, os testes funcionais são guardados dentro do diretório
+`test/functional/`. Para o Jobeet, os testes serão colocados no sub-diretório
+`test/functional/frontend/` pois cada aplicação tem o seu próprio
+sub-diretório. Esse diretório já contém dois arquivos: `categoryActionsTest.php`
+e `jobActionsTest.php`, isso porque todos os comandos que geram módulos criam
+um arquivo básico de teste funcional:
+
+ [php]
+ // test/functional/frontend/categoryActionsTest.php
+ include(dirname(__FILE__).'/../../bootstrap/functional.php');
+
+ $browser = new sfTestFunctional(new sfBrowser());
+
+ $browser->
+ get('/category/index')->
+
+ with('request')->begin()->
+ isParameter('module', 'category')->
+ isParameter('action', 'index')->
+ end()->
+
+ with('response')->begin()->
+ isStatusCode(200)->
+ checkElement('body', '!/This is a temporary page/')->
+ end()
+ ;
+
+À primeira vista, o script acima pode parecer um pouco estranho. Isso acontece
+porque os métodos de `sfBrowser` e `sfTestFunctional` implementam uma
+[interface fluente](http://en.wikipedia.org/wiki/Fluent_interface) que sempre
+retorna `$this`. Isso permite que você encadeie chamadas de métodos melhorando
+a legibilidade. O trecho acima é equivalente a:
+
+ [php]
+ // test/functional/frontend/categoryActionsTest.php
+ include(dirname(__FILE__).'/../../bootstrap/functional.php');
+
+ $browser = new sfTestFunctional(new sfBrowser());
+
+ $browser->get('/category/index');
+ $browser->with('request')->begin();
+ $browser->isParameter('module', 'category');
+ $browser->isParameter('action', 'index');
+ $browser->end();
+
+ $browser->with('response')->begin();
+ $browser->isStatusCode(200);
+ $browser->checkElement('body', '!/This is a temporary page/');
+ $browser->end();
+
+Os testes são rodados dentre de um bloco de contexto de teste. Um bloco de
+contexto de teste começa com `with('TESTER NAME')->begin()` e termina com
+`end()`:
+
+ [php]
+ $browser->
+ with('request')->begin()->
+ isParameter('module', 'category')->
+ isParameter('action', 'index')->
+ end()
+ ;
+
+O código testa se o parâmetro da requisição `module` é igual a `category` e
+se `action` é igual a `index`.
+
+>**TIP**
+>Quando você precisar chamar apenas um método de teste em um testador, você
+>não precisa criar um bloco:
+>`with('request')->isParameter('module', 'category')`.
+
+### O Testador de Requisição
+
+O **testador de requisições HTTP** fornece métodos testadores para analisar
+internamente e testar o objeto `sfWebRequest`:
+
+ | Método | Descrição
+ | ------------------ | ------------------------------------------------
+ | `isParameter()` | Verifica o valor de um parâmetro da requisição
+ | `isFormat()` | Verifica o formato de uma requisição
+ | `isMethod()` | Verifica o método
+ | `hasCookie()` | Verifica se a requisição tem um cookie com um
+ | | nome determinado
+ | `isCookie()` | Verifica o valor de um cookie
+
+### O Testador de Reposta
+
+Existe também uma classe **testadora de respostas HTTP** que fornece métodos
+testadores direcionados ao objeto `sfWebResponse`:
+
+ | Método | Descrição
+ | ------------------ | -----------------------------------------------------
+ | `checkElement()` | Verifica se o seletor CSS de uma resposta casa com
+ | | algum critério
+ | `checkForm()` | Verifica um objeto formulário `sfForm`
+ | `debug()` | Imprime a saída da resposta facilitando a depuração
+ | `matches()` | Testa uma resposta com uma expressão regular
+ | `isHeader()` | Verifica o valor do cabeçalho
+ | `isStatusCode()` | Verifica o código de status da resposta
+ | `isRedirected()` | Verifica se a página atual é um redirecionamento
+ | `isValid()` | Verifica se uma resposta é um XLM bem-formado
+ | | (você também pode validar a resposta novamente no
+ | | seu documento passando `true` como um argumento)
+
+>**NOTE**
+>Descreveremos mais classes testadoras nos próximos dias
+>(para formulários, usuário, cache, ...)
+
+Rodando Testes Funcionais
+-------------------------
+
+Assim como nos testes unitários, rodar os testes funcionais pode ser feito
+executando o arquivo de teste diretamente:
+
+ $ php test/functional/frontend/categoryActionsTest.php
+
+Ou então usando o comando `test:functional`:
+
+ $ php symfony test:functional frontend categoryActions
+
+
+
+Dados de Teste
+--------------
+
+Assim como nos testes unitários do ##ORM##, precisamos carregar dados de teste
+toda vez que iniciamos um teste funcional. Podemos reutilizar o código que
+escrevemos anteriormente:
+
+ [php]
+ include(dirname(__FILE__).'/../../bootstrap/functional.php');
+
+ $browser = new sfTestFunctional(new sfBrowser());
+
+ $loader = new sfPropelData();
+ $loader->loadData(sfConfig::get('sf_test_dir').'/fixtures');
+
+
+ Doctrine_Core::loadData(sfConfig::get('sf_test_dir').'/fixtures');
+
+
+Carregar dados em um teste funcional é um pouco mais fácil do que nos testes
+funcionais pois o banco de dados já foi inicializado pelo script bootstrap.
+
+Como nos testes unitários, não iremos copiar e colar esse trecho de código em
+cada arquivo de teste, em vez disso criaremos nossas próprias classes
+funcionais que herdam da `sfTestFunctional`:
+
+ [php]
+ // lib/test/JobeetTestFunctional.class.php
+ class JobeetTestFunctional extends sfTestFunctional
+ {
+ public function loadData()
+ {
+
+ $loader = new sfPropelData();
+ $loader->loadData(sfConfig::get('sf_test_dir').'/fixtures');
+
+
+ Doctrine_Core::loadData(sfConfig::get('sf_test_dir').'/fixtures');
+
+
+ return $this;
+ }
+ }
+
+Escrevendo Testes Funcionais
+----------------------------
+
+Escrever testes funcionais é como rodar um cenário em um navegador. Nós já
+escrevemos todos os cenários que precisamos testar nas stories do dia 2.
+
+Primeiro, vamos testar a página inicial do Jobeet editando o arquivo de teste
+`jobActionsTest.php`. Substitua o código com o seguinte:
+
+### Empregos expirados não devem ser listados
+
+ [php]
+ // test/functional/frontend/jobActionsTest.php
+ include(dirname(__FILE__).'/../../bootstrap/functional.php');
+
+ $browser = new JobeetTestFunctional(new sfBrowser());
+ $browser->loadData();
+
+ $browser->info('1 - The homepage')->
+ get('/')->
+ with('request')->begin()->
+ isParameter('module', 'job')->
+ isParameter('action', 'index')->
+ end()->
+ with('response')->begin()->
+ info(' 1.1 - Expired jobs are not listed')->
+ checkElement('.jobs td.position:contains("expired")', false)->
+ end()
+ ;
+
+Como no `lime`, uma mensagem informacional pode ser inserida chamando o método
+`info()` para deixar a saída mais legível. Para verificar a exclusão dos
+empregos expirados da página inicial, verificamos se o seletor CSS
+`.jobs td.position:contains("expired")` não casa com nada no conteúdo HTML da
+resposta (lembre-se que nos arquivos fixtures, o único emprego expirado que
+criamos contém "expired" no campo cargo). Quando o segundo argumento do método
+`checkElement()` for um Boolean, o método testa a existência de nós que casem
+com o seletor CSS.
+
+>**TIP**
+>O método `checkElement()` é capaz de interpretar a maioria dos seletores
+CSS3 válidos.
+
+### Apenas n empregos são listados para uma categoria
+
+Adicione o seguinte código no fim do arquivo de teste:
+
+ [php]
+ // test/functional/frontend/jobActionsTest.php
+ $max = sfConfig::get('app_max_jobs_on_homepage');
+
+ $browser->info('1 - The homepage')->
+ get('/')->
+ info(sprintf(' 1.2 - Only %s jobs are listed for a category', $max))->
+ with('response')->
+ checkElement('.category_programming tr', $max)
+ ;
+
+O método `checkElement()` também pode verificar se o seletor CSS casa 'n' nós
+no documento passando um inteiro como seu segundo argumento.
+
+### Uma categoria tem um link para a página da categoria apenas se tiver muitos empregos
+
+ [php]
+ // test/functional/frontend/jobActionsTest.php
+ $browser->info('1 - The homepage')->
+ get('/')->
+ info(' 1.3 - A category has a link to the category page only if too many jobs')->
+ with('response')->begin()->
+ checkElement('.category_design .more_jobs', false)->
+ checkElement('.category_programming .more_jobs')->
+ end()
+ ;
+
+Nesses testes, podemos verificar se não existe o link "mais empregos" para a
+categoria design (`.category_design .more_jobs` não existe), e se existe
+um link "mais empregos" para a categoria programming
+(`.category_programming .more_jobs` existe).
+
+### Os empregos são ordenados por data
+
+ [php]
+
+ // most recent job in the programming category
+ $criteria = new Criteria();
+ $criteria->add(JobeetCategoryPeer::SLUG, 'programming');
+ $category = JobeetCategoryPeer::doSelectOne($criteria);
+
+ $criteria = new Criteria();
+ $criteria->add(JobeetJobPeer::EXPIRES_AT, time(), Criteria::GREATER_THAN);
+ $criteria->add(JobeetJobPeer::CATEGORY_ID, $category->getId());
+ $criteria->addDescendingOrderByColumn(JobeetJobPeer::CREATED_AT);
+
+ $job = JobeetJobPeer::doSelectOne($criteria);
+
+
+ $q = Doctrine_Query::create()
+ ->select('j.*')
+ ->from('JobeetJob j')
+ ->leftJoin('j.JobeetCategory c')
+ ->where('c.slug = ?', 'programming')
+ ->andWhere('j.expires_at > ?', date('Y-m-d', time()))
+ ->orderBy('j.created_at DESC');
+
+ $job = $q->fetchOne();
+
+
+ $browser->info('1 - The homepage')->
+ get('/')->
+ info(' 1.4 - Jobs are sorted by date')->
+ with('response')->begin()->
+ checkElement(sprintf('.category_programming tr:first a[href*="/%d/"]', $job->getId()))->
+ end()
+ ;
+
+Para testar se os empregos estão realmente ordenados por data, precisamos
+verificar se o primeiro emprego listado na página inicial é o que esperamos.
+Isso pode ser feito verificando se a URL contém a chave primária esperada.
+Como a chave primária pode mudar entre as execuções, precisamos primeiro pegar
+o objeto ##ORM## do banco de dados.
+
+Mesmo se o teste funcionar dessa forma, precisamos refatorar o código um pouco,
+assim se pegarmos o primeiro emprego da categoria programming podemos
+reutilizá-lo em qualquer lugar nos nossos testes. Nós não moveremos o código
+para a camada Model pois o código é específico para os testes. Em vez disso,
+iremos mover o código para a classe `JobeetTestFunctional` que criamos mais
+cedo. Essa classe funciona com um Testador Específico de Domínio do Jobeet:
+
+ [php]
+ // lib/test/JobeetTestFunctional.class.php
+ class JobeetTestFunctional extends sfTestFunctional
+ {
+ public function getMostRecentProgrammingJob()
+ {
+
+ // most recent job in the programming category
+ $criteria = new Criteria();
+ $criteria->add(JobeetCategoryPeer::SLUG, 'programming');
+ $category = JobeetCategoryPeer::doSelectOne($criteria);
+
+ $criteria = new Criteria();
+ $criteria->add(JobeetJobPeer::EXPIRES_AT, time(), Criteria::GREATER_THAN);
+ $criteria->add(JobeetJobPeer::CATEGORY_ID, $category->getId());
+ $criteria->addDescendingOrderByColumn(JobeetJobPeer::CREATED_AT);
+
+ return JobeetJobPeer::doSelectOne($criteria);
+
+
+ $q = Doctrine_Query::create()
+ ->select('j.*')
+ ->from('JobeetJob j')
+ ->leftJoin('j.JobeetCategory c')
+ ->where('c.slug = ?', 'programming');
+ $q = Doctrine_Core::getTable('JobeetJob')->addActiveJobsQuery($q);
+
+ return $q->fetchOne();
+
+ }
+
+ // ...
+ }
+
+Agora você pode substituir o código do teste anterior com o seguinte:
+
+ [php]
+ // test/functional/frontend/jobActionsTest.php
+ $browser->info('1 - The homepage')->
+ get('/')->
+ info(' 1.4 - Jobs are sorted by date')->
+ with('response')->begin()->
+ checkElement(sprintf('.category_programming tr:first a[href*="/%d/"]',
+ $browser->getMostRecentProgrammingJob()->getId()))->
+ end()
+ ;
+
+### Todo emprego na página inicial é clicável
+
+ [php]
+ $job = $browser->getMostRecentProgrammingJob();
+
+ $browser->info('2 - The job page')->
+ get('/')->
+
+ info(' 2.1 - Each job on the homepage is clickable and give detailed information')->
+ click('Web Developer', array(), array('position' => 1))->
+ with('request')->begin()->
+ isParameter('module', 'job')->
+ isParameter('action', 'show')->
+ isParameter('company_slug', $job->getCompanySlug())->
+ isParameter('location_slug', $job->getLocationSlug())->
+ isParameter('position_slug', $job->getPositionSlug())->
+ isParameter('id', $job->getId())->
+ end()
+ ;
+
+Para testar o link do emprego na página inicial, simulamos um clique no texto
+"Web Developer". Como existem muitos deles na página, dizemos explicitamente
+para o navegador clicar no primeiro (`array('position' => 1)`).
+
+Cada parâmetro da requisição é então testado para garantir que o roteamento
+foi feito corretamente para o emprego.
+
+Aprenda pelo Exemplo
+--------------------
+
+Nessa seção, nós fornecemos todo o código necessário para testar as páginas de
+emprego e categoria. Leia o código cuidadosamente para que você possa aprender
+alguns truques novos e elegantes:
+
+ [php]
+ // lib/test/JobeetTestFunctional.class.php
+ class JobeetTestFunctional extends sfTestFunctional
+ {
+ public function loadData()
+ {
+
+ $loader = new sfPropelData();
+ $loader->loadData(sfConfig::get('sf_test_dir').'/fixtures');
+
+
+ Doctrine_Core::loadData(sfConfig::get('sf_test_dir').'/fixtures');
+
+
+ return $this;
+ }
+
+ public function getMostRecentProgrammingJob()
+ {
+
+ // most recent job in the programming category
+ $criteria = new Criteria();
+ $criteria->add(JobeetCategoryPeer::SLUG, 'programming');
+ $category = JobeetCategoryPeer::doSelectOne($criteria);
+
+ $criteria = new Criteria();
+ $criteria->add(JobeetJobPeer::EXPIRES_AT, time(), Criteria::GREATER_THAN);
+ $criteria->addDescendingOrderByColumn(JobeetJobPeer::CREATED_AT);
+
+ return JobeetJobPeer::doSelectOne($criteria);
+
+
+ $q = Doctrine_Query::create()
+ ->select('j.*')
+ ->from('JobeetJob j')
+ ->leftJoin('j.JobeetCategory c')
+ ->where('c.slug = ?', 'programming');
+ $q = Doctrine_Core::getTable('JobeetJob')->addActiveJobsQuery($q);
+
+ return $q->fetchOne();
+
+ }
+
+ public function getExpiredJob()
+ {
+
+ // expired job
+ $criteria = new Criteria();
+ $criteria->add(JobeetJobPeer::EXPIRES_AT, time(), Criteria::LESS_THAN);
+
+ return JobeetJobPeer::doSelectOne($criteria);
+
+
+ $q = Doctrine_Query::create()
+ ->from('JobeetJob j')
+ ->where('j.expires_at < ?', date('Y-m-d', time()));
+
+ return $q->fetchOne();
+
+ }
+ }
+
+ // test/functional/frontend/jobActionsTest.php
+ include(dirname(__FILE__).'/../../bootstrap/functional.php');
+
+ $browser = new JobeetTestFunctional(new sfBrowser());
+ $browser->loadData();
+
+ $browser->info('1 - The homepage')->
+ get('/')->
+ with('request')->begin()->
+ isParameter('module', 'job')->
+ isParameter('action', 'index')->
+ end()->
+ with('response')->begin()->
+ info(' 1.1 - Expired jobs are not listed')->
+ checkElement('.jobs td.position:contains("expired")', false)->
+ end()
+ ;
+
+ $max = sfConfig::get('app_max_jobs_on_homepage');
+
+ $browser->info('1 - The homepage')->
+ info(sprintf(' 1.2 - Only %s jobs are listed for a category', $max))->
+ with('response')->
+ checkElement('.category_programming tr', $max)
+ ;
+
+ $browser->info('1 - The homepage')->
+ get('/')->
+ info(' 1.3 - A category has a link to the category page only if too many jobs')->
+ with('response')->begin()->
+ checkElement('.category_design .more_jobs', false)->
+ checkElement('.category_programming .more_jobs')->
+ end()
+ ;
+
+ $browser->info('1 - The homepage')->
+ info(' 1.4 - Jobs are sorted by date')->
+ with('response')->begin()->
+ checkElement(sprintf('.category_programming tr:first a[href*="/%d/"]', $browser->getMostRecentProgrammingJob()->getId()))->
+ end()
+ ;
+
+ $job = $browser->getMostRecentProgrammingJob();
+
+ $browser->info('2 - The job page')->
+ get('/')->
+
+ info(' 2.1 - Each job on the homepage is clickable and give detailed information')->
+ click('Web Developer', array(), array('position' => 1))->
+ with('request')->begin()->
+ isParameter('module', 'job')->
+ isParameter('action', 'show')->
+ isParameter('company_slug', $job->getCompanySlug())->
+ isParameter('location_slug', $job->getLocationSlug())->
+ isParameter('position_slug', $job->getPositionSlug())->
+ isParameter('id', $job->getId())->
+ end()->
+
+ info(' 2.2 - A non-existent job forwards the user to a 404')->
+ get('/job/foo-inc/milano-italy/0/painter')->
+ with('response')->isStatusCode(404)->
+
+ info(' 2.3 - An expired job page forwards the user to a 404')->
+ get(sprintf('/job/sensio-labs/paris-france/%d/web-developer', $browser->getExpiredJob()->getId()))->
+ with('response')->isStatusCode(404)
+ ;
+
+ // test/functional/frontend/categoryActionsTest.php
+ include(dirname(__FILE__).'/../../bootstrap/functional.php');
+
+ $browser = new JobeetTestFunctional(new sfBrowser());
+ $browser->loadData();
+
+ $browser->info('1 - The category page')->
+ info(' 1.1 - Categories on homepage are clickable')->
+ get('/')->
+ click('Programming')->
+ with('request')->begin()->
+ isParameter('module', 'category')->
+ isParameter('action', 'show')->
+ isParameter('slug', 'programming')->
+ end()->
+
+ info(sprintf(' 1.2 - Categories with more than %s jobs also have a "more" link', sfConfig::get('app_max_jobs_on_homepage')))->
+ get('/')->
+ click('27')->
+ with('request')->begin()->
+ isParameter('module', 'category')->
+ isParameter('action', 'show')->
+ isParameter('slug', 'programming')->
+ end()->
+
+ info(sprintf(' 1.3 - Only %s jobs are listed', sfConfig::get('app_max_jobs_on_category')))->
+ with('response')->checkElement('.jobs tr', sfConfig::get('app_max_jobs_on_category'))->
+
+ info(' 1.4 - The job listed is paginated')->
+ with('response')->begin()->
+ checkElement('.pagination_desc', '/32 jobs/')->
+ checkElement('.pagination_desc', '#page 1/2#')->
+ end()->
+
+ click('2')->
+ with('request')->begin()->
+ isParameter('page', 2)->
+ end()->
+ with('response')->checkElement('.pagination_desc', '#page 2/2#')
+ ;
+
+Depurando Testes Funcionais
+---------------------------
+
+Às vezes um teste funcional falha. Como o symfony simula um navegador sem
+nenhuma interface gráfica, pode ser difícil para diagnosticar o problema.
+Pensando nisso o symfony fornece o método `~debug|Debug~()` para mostrar a
+saída do cabeçalho e conteúdo da resposta.
+
+ [php]
+ $browser->with('response')->debug();
+
+O método `debug()` pode ser inserido em qualquer lugar de um bloco testador
+`response` e irá parar a execução do script.
+
+Functional Tests Harness
+------------------------
+
+O comando `test:functional` também pode ser usado para iniciar todos os testes
+funcionais de uma aplicação:
+
+ $ php symfony test:functional frontend
+
+A saída do comando é uma única linha para cada um dos arquivos de teste:
+
+
+
+Tests Harness
+-------------
+
+Como você pode esperar, existe também um comando para iniciar todos os testes
+de um projeto (unitários e funcionais):
+
+ $ php symfony test:all
+
+
+
+Quando você tem um conjunto grande de testes, pode ser bem demorado para
+iniciar todos os testes cada vez que você fizer uma mudança, especialmente se
+alguns dos testes falharem. Isso porque, cada vez que você arruma um teste, você
+deve rodar o conjunto de testes inteiro novamente para garantir que você não
+quebrou nenhuma outra parte. Mas até que os testes falhados não forem
+arrumados, não faz sentido re-executar todos os outros testes. O comando
+`test:all` tem uma opção `--only-failed` que força o comando para re-executar
+apenas os testes que falharam durante a última execução:
+
+ $ php symfony test:all --only-failed
+
+A primeira vez que você roda o comando, todos os testes são rodados como de
+costume. Mas para as execuções subsequentes, apenas os testes que falharam
+na última vez serão executados. Assim que você consertar seu código, alguns testes
+passarão, e serão removidos das execuções subsequentes. Quando todos os testes
+passarem novamente, o conjunto de testes completo é executado... e isso se
+repete várias vezes.
+
+>**TIP**
+>Se você quiser integrar seu conjunto de testes em um processo de integração
+>contínua, use a opção `--xml` para forçar que o comando `test:all` gere uma
+>saída XML compatível com o JUnit.
+>
+> $ php symfony test:all --xml=log.xml
+
+Considerações Finais
+--------------------
+
+Aqui termina nossa viagem pelas ferramentas de teste do symfony. Você não tem
+mais desculpa para não testar suas aplicações! Com o framework lime e o
+framework de testes funcionais, o symfony fornece ferramentas poderosas para
+te ajudar a escrever testes com pouco esforço.
+
+Nós demos apenas uma pincelada nos testes funcionais. A partir de agora, toda
+vez que implementar uma funcionalidade, também escreveremos testes para
+aprender mais funcionalidades do framework de teste.
+
+Amanhã, falaremos sobre outra excelente funcionalidade do symfony: o
+**framework de formulários**.
+
+Feedback
+--------
+>**Dica - pt_BR**
+>Este capítulo foi traduzido por **Rogerio Prado de Jesus**.
+>Se encontrar algum erro que deseja corrigir ou quiser fazer algum comentário
+>não deixe de enviar um e-mail para **rogeriopradoj [at] gmail.com**
+
+>**Tip - en**
+>This chapter was translated by **Rogerio Prado Jesus**.
+>If you find any errors to be corrected or you have any comments
+>do not hesitate to send an email to **rogeriopradoj [at] gmail.com**
+
+
+__ORM__
+