Desastre de teste pronunciado... Acho que você pode deixar de fora a parte -db- se quiser uma palavra um pouco mais curta e se sentir inclinado.
Test-DB-Acle é uma biblioteca PHP para facilitar a escrita de testes fáceis e concisos para a camada de banco de dados.
Acredito que escrever testes deve ser o mais fácil possível para o desenvolvedor e também deve ser o mais fácil de ler possível para outros desenvolvedores aprenderem.
Isso significa que quaisquer dados de teste no teste devem ser relevantes apenas para o cenário de teste. A maioria das tabelas de banco de dados, entretanto, possui colunas não nulas que exigem que você insira dados fictícios que estão apenas introduzindo ruído cognitivo no teste.
Test-Db-Acle visa tirar esse fardo do desenvolvedor. A estrutura de teste não faz nenhuma suposição sobre como funcionam as classes da camada de banco de dados, se elas usam um ORM como Doctrine, procedimentos armazenados ou SQL direto, o princípio é sempre o mesmo, em algum ponto o código interage com os dados nas tabelas do banco de dados , e precisamos testar isso.
Instalação via compositor
desativa verificações de chave estrangeira no banco de dados
lida automaticamente com colunas não nulas
corta automaticamente colunas de data/hora no mysql quando a afirmação de valores está em tabelas db - útil para carimbos de data e hora inseridos (no Sqlite essas colunas devem ser especificadas)
praticamente todos os componentes podem ser trocados e substituídos por variedades personalizadas
suporta Mysql e SQLite atualmente
É independente de estrutura, não faz suposições se ORMs são usados, por exemplo, e devem ser facilmente adaptáveis para outras estruturas de teste unitário.
Os bancos de dados suportados são, atualmente, MySql (e por extensão MariaDB) e Sqlite.
A arquitetura deverá permitir a adição de mais bases de dados.
Esta biblioteca pode ser usada imediatamente com PHPUnit. Deve ser bastante fácil usá-lo com outras estruturas de teste usando as características fornecidas e fazendo com que o método 'assertEquals' seja delegado ao método equivalente (por exemplo, lembro-me de ser 'assertEqual' no SimpleTest)
Forneci um TestDbAclePhpUnitAbstractTestCase simples, bem como TestDbAclePhpUnitTraitsDatabaseHelperTrait se você estiver usando PHP 5.4 e não se importa em usar características.
Ok, para ser justo, testar a camada de banco de dados é caro e retarda os testes e, sempre que possível, quaisquer dependências do banco de dados devem ser ridicularizadas. Mas às vezes só temos que fazer isso, esperançosamente em uma aplicação bem estruturada isso pode ser reduzido ao mínimo.
Existem muitas ferramentas e abordagens disponíveis (por exemplo, DBUnit ou uso de métodos de fábrica em seus testes unitários) para ajudar nos testes de banco de dados, cada uma com seus pontos fortes. Essa abordagem funciona para mim porque:
Não preciso me preocupar com colunas nulas ou restrições de chave estrangeira
Eu forneço um conjunto mínimo de dados para meus testes
Posso ver os dados de teste em formato de grade acima dos testes e novamente ao declarar os dados no banco de dados.
Então eu configurei minha própria solução.
###Então, como funciona e como é? Mostre-me um exemplo!###
A ideia é usar uma string de texto com "valores separados por pipe", vamos chamá-la de PSV - como em CSV, mas com pipes - para configurar equipamentos de teste como este:
(O formato do PSV é muito semelhante ao formato usado pela excelente estrutura Behat BDD (https://github.com/Behat/Behat))
$dbTablesToSetup="[table_name]id |date |name |value |dependent_table_id10 |2001-01-01 |foo |900 |60[dependent_table]id |name20 |Bar60 |Baz";//use isto se você não quiser use as características fornecidas ou casos de teste abstratos$testDbAcle = TestDbAcleTestDbAcle::create($pdo);$testDbAcle->runCommand(new TestDbAcleCommandsSetupTablesCommand($dbTablesToSetup));//use isto se você estendeu seu caso de teste de TestDbAclePhpUnitAbstractTestCase ou está usando o TestDbAclePhpUnitTraitsDatabaseHelperTrait:$this->setupTables($dbTablesToSetup);
A própria estrutura sabe quais colunas não são NULL na tabela e insere valores padrão... Na verdade, vamos supor que a tabela table_name tenha 30 colunas, todas elas não nulas....
Além disso, pode haver várias restrições de chave estrangeira em segundo plano. Test-Db-Acle desativa temporariamente as verificações de chave estrangeira, portanto, não precisamos nos preocupar com isso ou com a ordem em que inserimos os dados de teste.
###Que tal um teste real...?### Primeiro, se você usa PHP5.4, você pode usar a versão traits:
classe ExemploTest estende PHPUnit_Framework_TestCase implementa TestDbAclePhpUnitAbstractTestCaseInterface {use TestDbAclePhpUnitTraitsDatabaseHelperTrait; /** * Este método precisa ser implementado, ele deve retornar o objeto PDO que será utilizado nos fixtures do banco de dados * * @return Pdo */public function providePdo() {return new Pdo("mysql:dbname=my_db_tests;host=localhost",'myTestUser', 'myTestPassword'); } /* * Um exemplo de teste */função pública test_AddressService() {$this->setupTables("[endereço] address_id |empresa 1 |me 3 |você [usuário] user_id |nome 10 |John 20 |Mary "); $this->setAutoIncrement('endereço', 100); $this->addressService->addEntry("them");$this->assertTableStateContains(" [endereço] address_id |empresa 1 |me 3 |você 100 |eles [usuário] user_id |nome 10 |John 20 |Mary ", array(), "Coisas funcionam"); } }
Se você não usar características, poderá usar AbstractTestCase
, mas não poderá usar suas próprias classes de teste básicas nesse caso.
classe ExemploTest estende TestDbAclePhpUnitAbstractTestCase { protegido $addressService;function Setup(){parent::Setup();$this->addressService = new ServicesAddressService(); }/** * Este método precisa ser implementado, ele deve retornar o objeto PDO que será utilizado nos fixtures do banco de dados * * @return Pdo */public function providePdo() {return new Pdo("mysql:dbname=my_db_tests;host=localhost",'myTestUser', 'myTestPassword'); }função test_AddressService() {$this->setupTables("[endereço] address_id |empresa 1 |me 3 |você [usuário] user_id |nome 10 |John 20 |Mary "); $this->setAutoIncrement('endereço', 100); $this->addressService->addEntry("them");$this->assertTableStateContains(" [endereço] address_id |empresa 1 |me 3 |você 100 |eles [usuário] user_id |nome 10 |John 20 |Mary ", array(), "Coisas funcionam"); } }
Ok, obviamente ServicesAddressService não existe aqui (ei, é um teste primeiro, certo?) E o exemplo é bastante simples.
Na vida real, eu colocaria o método getPdo em uma classe de teste base comum para o projeto e ele poderia ser obtido de maneira bem diferente do que aqui. Mas, bem, este é um exemplo.
Como você pode ver, setupTables pode configurar várias tabelas ao mesmo tempo e assertTableStateContains também pode verificar o estado de várias tabelas ao mesmo tempo.
Da mesma forma que setupTables pode configurar tabelas que possuem muito mais colunas do que as especificadas, assertTableStateContains apenas compara e afirma os valores das colunas especificadas também.
A maneira mais fácil de instalar o Test-Db-Acle é usando o compositor (Leia mais aqui: http://packagist.org), e eu recomendo usar essa abordagem, embora você também possa descompactar o pacote em uma pasta e ativar o carregamento automático para manualmente na forma que desejar (usa a convenção de nomenclatura psr-0)
Para usar com o compositor, adicione isto ao seu arquivo compositor.json:
"require": { "test-db-acle/test-db-acle" : "dev-master" }, "repositories" : [ { "type": "git", "url": "https://github.com/malteriesch/test-db-acle.git" } ]
Você também pode usar https://packagist.org/packages/test-db-acle/test-db-acle se preferir.
Contribuições (e críticas) são mais que bem-vindas...!
###Como executar os testes Test-Db-Acle### Para executar os testes, você precisará criar um banco de dados vazio em um servidor MySql de sua escolha, copiar testes/Functional/config.php.dist para testes/ Functional/config.php e preencha com os detalhes do seu banco de dados. Então, esperançosamente, todos os testes deverão ser executados. (Na verdade, o banco de dados só é necessário para o teste de fumaça funcional)
Sintaxe PSV
ResumoTestCase
Estendendo e customizando TestDbAcle
Registro de alterações