Diferentes métodos de teste
Primeiro defina o que você está fazendo: Teste de unidade ou teste de integração . O número de camadas é irrelevante para o teste de unidade, pois você provavelmente testa apenas uma classe. O resto você zomba. Para testes de integração, é inevitável que você teste várias camadas. Se você tiver bons testes de unidade, o truque é tornar os testes de integração não muito complexos.
Se seus testes de unidade forem bons, não será necessário repetir todos os detalhes ao realizar testes de integração.
Termos que usamos, esses são um pouco dependentes da plataforma, mas você pode encontrá-los em quase todas as plataformas de teste / desenvolvimento:
Exemplo de aplicação
Dependendo da tecnologia usada, os nomes podem diferir, mas usarei isso como um exemplo:
Se você possui um aplicativo CRUD simples com o modelo Product, ProductsController e uma visualização de índice que gera uma tabela HTML com produtos:
O resultado final do aplicativo está mostrando uma tabela HTML com uma lista de todos os produtos que estão ativos.
Teste de unidade
Modelo
O modelo que você pode testar com bastante facilidade. Existem métodos diferentes para isso; nós usamos luminárias. Eu acho que é isso que você chama de "conjuntos de dados falsos". Portanto, antes de cada teste ser executado, criamos a tabela e inserimos os dados originais. A maioria das plataformas possui métodos para isso. Por exemplo, na sua classe de teste, um método setUp () que é executado antes de cada teste.
Em seguida, executamos nosso teste, por exemplo: produtos testGetAllActive .
Então, testamos diretamente em um banco de dados de teste. Nós não zombamos da fonte de dados; nós sempre fazemos o mesmo. Isso nos permite, por exemplo, testar com uma nova versão do banco de dados, e quaisquer problemas de consulta surgirão.
No mundo real, você nem sempre pode seguir 100% de responsabilidade única . Se você quiser fazer isso ainda melhor, poderá usar uma fonte de dados que você zomba. Para nós (usamos um ORM) que parece testar a tecnologia já existente. Além disso, os testes se tornam muito mais complexos e realmente não testam as consultas. Então, mantemos assim.
Os dados codificados são armazenados separadamente nos equipamentos. Portanto, o equipamento é como um arquivo SQL com uma instrução create table e insere os registros que usamos. Nós os mantemos pequenos, a menos que haja uma necessidade real de testar com muitos registros.
class ProductModel {
public function getAllActive() {
return $this->find('all', array('conditions' => array('active' => 1)));
}
}
Controlador
O controlador precisa de mais trabalho, porque não queremos testar o modelo com ele. Então, o que fazemos é zombar do modelo. Isso significa: Testamos: método index () que deve retornar uma lista de registros.
Portanto, zombamos do método getAllActive () e adicionamos dados fixos (dois registros, por exemplo). Agora testamos os dados que o controlador envia para a visualização e comparamos se realmente recuperamos esses dois registros.
function testProductIndexLoggedIn() {
$this->setLoggedIn();
$this->ProductsController->mock('ProductModel', 'index', function(return array(your records) ));
$result=$this->ProductsController->index();
$this->assertEquals(2, count($result['products']));
}
É o bastante. Tentamos adicionar pouca funcionalidade ao controlador, pois isso dificulta o teste. Mas é claro que sempre há algum código nele. Por exemplo, testamos requisitos como: Mostrar esses dois registros apenas se você estiver conectado.
Portanto, o controlador precisa de um mock normalmente e de um pequeno pedaço de dados codificados. Para um sistema de login, talvez outro. Em nosso teste, temos um método auxiliar para isso: setLoggedIn (). Isso simplifica o teste com login ou sem login.
class ProductsController {
public function index() {
if($this->loggedIn()) {
$this->set('products', $this->ProductModel->getAllActive());
}
}
}
Visualizações
O teste de visualizações é difícil. Primeiro separamos a lógica que se repete. Colocamos em Helpers e testamos estritamente essas classes. Esperamos sempre a mesma saída. Por exemplo, generateHtmlTableFromArray ().
Depois, temos algumas visualizações específicas do projeto. Nós não testamos isso. Não é realmente desejado testá-los unitariamente. Nós os mantemos para testes de integração. Como colocamos grande parte do código em visualizações, temos um risco menor aqui.
Se você começar a testar aqueles, provavelmente precisará alterar seus testes sempre que alterar um pedaço de HTML que não é útil para a maioria dos projetos.
echo $this->tableHelper->generateHtmlTableFromArray($products);
Teste de integração
Dependendo da sua plataforma, aqui você pode trabalhar com histórias de usuários, etc. Ele pode ser baseado na Web como o Selenium ou outras soluções comparáveis.
Geralmente, apenas carregamos o banco de dados com os equipamentos e afirmamos quais dados devem estar disponíveis. Para testes de integração total, geralmente usamos requisitos muito globais. Portanto: defina o produto como ativo e verifique se o produto fica disponível.
Não testamos tudo novamente, como se os campos corretos estão disponíveis. Testamos os requisitos maiores aqui. Como não queremos duplicar nossos testes do controlador ou da exibição. Se algo realmente for essencial / essencial do seu aplicativo ou por motivos de segurança (verifique a senha NÃO está disponível), nós os adicionamos para garantir que esteja certo.
Os dados codificados são armazenados nos equipamentos.
function testIntegrationProductIndexLoggedIn() {
$this->setLoggedIn();
$result=$this->request('products/index');
$expected='<table';
$this->assertContains($expected, $result);
// Some content from the fixture record
$expected='<td>Product 1 name</td>';
$this->assertContains($expected, $result);
}