Fundamentos de TDDD (Test-Driven Database Development) com teste de unidade tSQLt
Este artigo fala sobre os principais conceitos de desenvolvimento de banco de dados orientado a teste, seguido pela criação de testes de unidade SQL simples com tSQLt com base nessa abordagem.
O teste de unidade SQL convencional existe há muito tempo, enquanto o desenvolvimento de banco de dados orientado a testes também não foi introduzido ontem, no entanto, mudar para essa metodologia de teste oferece experiência de teste de unidade pura com muito mais recursos e flexibilidade em comparação com sua contraparte.
Vamos ser apresentados com o desenvolvimento de banco de dados orientado a teste primeiro e, por favor, esteja preparado para mudar para ele se você ainda não estiver usando-o e estiver feliz em fazê-lo.
Sobre o desenvolvimento de banco de dados orientado a testes
É melhor definir primeiro o desenvolvimento de banco de dados orientado a testes, para que seja mais fácil explorá-lo ainda mais.
Definição simples
O método no qual os testes de unidade conduzem o processo de desenvolvimento de banco de dados é chamado de desenvolvimento de banco de dados orientado a teste ou TDDD.
Definição alternativa
O método de criar objetos de banco de dados com base na criação e execução de seus testes de unidade primeiro é chamado de desenvolvimento de banco de dados controlado por teste ou TDDD.
TDDD: Desenvolvimento ou testes?
Eu sei, pela primeira vez alunos, as definições acima não dão muitas informações sobre o desenvolvimento de banco de dados orientado a testes e, além disso, ainda não está claro se estamos falando de desenvolvimento de banco de dados ou teste de unidade de banco de dados?
A resposta curta é: ambos!
Sim, é basicamente teste de unidade SQL seguido de desenvolvimento de banco de dados, ao contrário do desenvolvimento de banco de dados seguido de teste de unidade SQL.
Posso ter acrescentado mais confusão agora. Portanto, é hora de esclarecer a confusão agora.
Testar a primeira abordagem
TDDD é basicamente uma abordagem de teste primeiro em que o desenvolvimento de banco de dados depende de testes de unidade para começar e assumir o controle.
A melhor maneira de entender isso é comparar o teste de unidade convencional com o desenvolvimento de banco de dados orientado a teste.
Desenvolvimento SQL convencional vs orientado a testes
Veja uma comparação simples entre o teste de unidade SQL convencional e o TDDD
Teste de unidade SQL convencional | Desenvolvimento de banco de dados orientado a testes |
|
|
Uma comparação mais abrangente entre ambas as metodologias é a seguinte:
Teste de unidade SQL convencional | Desenvolvimento de banco de dados orientado a testes |
|
|
Os pontos acima se tornam mais compreensíveis à medida que você avança para as próximas seções deste artigo.
Para saber mais sobre o teste de unidade SQL convencional, consulte o artigo “Teste de unidade SQL convencional com tSQLt em palavras simples”
Benefícios do desenvolvimento de banco de dados orientado a testes
Há uma série de benefícios do uso do desenvolvimento de banco de dados orientado a testes, mas vamos mencionar apenas alguns benefícios importantes do TDDD para destacar sua importância.
Encapsulamento de lógica de negócios
Um dos benefícios mais notáveis do desenvolvimento de banco de dados orientado a teste é o encapsulamento da lógica de negócios nos testes de unidade, em vez de objetos de banco de dados.
Por exemplo, um requisito de negócios para que o usuário final possa adicionar um novo livro ao sistema de bibliotecas deve ser atendido escrevendo um teste de unidade para garantir que o objeto de banco de dados responsável por adicionar o novo livro ao sistema de bibliotecas faça seu trabalho corretamente.
Em palavras simples, procuramos os testes de unidade em vez de objetos de banco de dados para ver se os objetos estão fazendo seu trabalho corretamente ou não e, dessa forma, a lógica de negócios é ocultada em testes de unidade em vez de objetos.
Cobertura total de testes
O desenvolvimento de banco de dados orientado a teste oferece cobertura total de teste em comparação com o teste de unidade de banco de dados convencional.
A cobertura total de testes significa que todos os nossos testes unitários estão cobrindo todos os objetos de banco de dados que são responsáveis por atender aos requisitos técnicos ou de negócios.
Detecção precoce de bugs
O desenvolvimento de banco de dados orientado a teste ajuda na detecção precoce de bugs, já que os testes de unidade SQL estão na linha de frente da gravação de código de objeto de banco de dados.
Em outras palavras, como todos os testes de unidade são escritos primeiro e não são considerados corretos até que passem, isso ajuda na detecção precoce de bugs.
Desenvolvimento focado em requisitos
Outro benefício muito útil do desenvolvimento de banco de dados orientado a testes é que, ele só requer que você desenvolva o que é exigido pelos negócios.
Como seus objetos de banco de dados são totalmente baseados em testes de unidade e seus testes de unidade são gravados apenas para atender aos requisitos de negócios, portanto, a codificação de banco de dados desnecessária pode ser evitada e isso economiza muito tempo e esforço.
Por exemplo, para atender a um requisito de negócios, adicionar um novo livro ao sistema de bibliotecas não requer que você forneça funcionalidade de pesquisa também, uma vez que você está preocupado apenas com o que é necessário.
Implementando o desenvolvimento de banco de dados orientado a testes
Vamos agora pular para implementar o desenvolvimento de banco de dados orientado a testes com testes de unidade tSQLt levando em conta um cenário simples.
Por que tSQLt com desenvolvimento de banco de dados orientado a testes?
O tSQLt é uma das estruturas de teste de unidade SQL mais avançadas e oferece suporte ao desenvolvimento de banco de dados orientado a teste por padrão.
O tSQLt foi escrito de tal forma que é por design, facilita a abordagem de teste primeiro e é isso que você vai experimentar nesta seção.
- Nota: Para entender melhor o tSQLt, leia o seguinte artigo tSQLt – A Forgotten Treasure in Database Unit Testing
Pré-requisitos
Este artigo pressupõe que os leitores tenham compreensão geral de teste de unidade de banco de dados e T-SQL e possam escrever confortavelmente scripts de banco de dados simples.
Este artigo também pressupõe que os leitores estejam familiarizados com a estrutura de teste de unidade tSQLt.
Banco de dados de exemplo de instalação
Estamos criando um banco de dados de exemplo que consiste nas seguintes tabelas:
- Autor
- Artigo
Vamos criar um banco de dados de exemplo SQLDevArticlesV3 executando o seguinte script:
-- 1 Create SQLDevArticlesV3 database
CREATE DATABASE SQLDevArticlesV3;
GO
USE SQLDevArticlesV3;
GO
-- 2 Create author table
CREATE TABLE [dbo].[Author] (
[AuthorId] INT IDENTITY (1, 1) NOT NULL,
[Name] VARCHAR (40) NOT NULL,
[RegistrationDate] DATETIME2 (7) NULL
);
-- 3 Create article tables
CREATE TABLE [dbo].[Article] (
[ArticleId] INT IDENTITY (1, 1) NOT NULL,
[Title] VARCHAR (300) NOT NULL,
[Published_Date] DATETIME2 (7) NOT NULL
);
-- 4 Populate author table
SET IDENTITY_INSERT [dbo].[Author] ON
INSERT INTO [dbo].[Author] ([AuthorId], [Name], [RegistrationDate]) VALUES (1, N'Asif', N'2018-01-01 00:00:00')
INSERT INTO [dbo].[Author] ([AuthorId], [Name], [RegistrationDate]) VALUES (2, N'Peter', N'2018-02-01 00:00:00')
INSERT INTO [dbo].[Author] ([AuthorId], [Name], [RegistrationDate]) VALUES (3, N'Sarah', N'2018-03-02 00:00:00')
INSERT INTO [dbo].[Author] ([AuthorId], [Name], [RegistrationDate]) VALUES (4, N'Adil', N'2018-04-02 00:00:00')
INSERT INTO [dbo].[Author] ([AuthorId], [Name], [RegistrationDate]) VALUES (5, N'Sam', N'2019-01-01 00:00:00')
SET IDENTITY_INSERT [dbo].[Author] OFF
-- 5 Populate article table
SET IDENTITY_INSERT [dbo].[Article] ON
INSERT INTO [dbo].[Article] ([ArticleId], [Title], [Published_Date]) VALUES (1, N'Fundamentals of Database Programming', N'2018-01-02 00:00:00')
INSERT INTO [dbo].[Article] ([ArticleId], [Title], [Published_Date]) VALUES (2, N'Advanced Database Programming', N'2018-01-03 00:00:00')
INSERT INTO [dbo].[Article] ([ArticleId], [Title], [Published_Date]) VALUES (3, N'Understanding SQL Stored Procedures ', N'2018-02-02 00:00:00')
INSERT INTO [dbo].[Article] ([ArticleId], [Title], [Published_Date]) VALUES (4, N'Database Design Concepts', N'2018-03-02 00:00:00')
INSERT INTO [dbo].[Article] ([ArticleId], [Title], [Published_Date]) VALUES (5, N'Power BI Desktop Fundamentals', N'2019-01-02 00:00:00')
SET IDENTITY_INSERT [dbo].[Article] OFF;
GO
Como resultado da execução do script acima, você vê o banco de dados de exemplo sendo criado.
Instalar a estrutura de teste de unidade tSQLt
Faça o download da estrutura de teste de unidade tSQLt do tSQLt.org.
Consulte o artigo Teste de unidade SQL convencional com tSQLt no Simple Words para entender melhor como instalar a estrutura de teste de unidade tSQLt se você não a tiver instalado antes.
Abra o arquivo tSQLt.class.sql no SSMS (SQL Server Management Studio) e execute o script tSQL.class.sql no banco de dados de exemplo SQLDevArticlesV3.
Então, o banco de dados de exemplo foi configurado e a estrutura de teste de unidade tSQLt também foi adicionada a ele, o que significa que estamos prontos para ir.
Requisitos de negócios
Um requisito de negócios informando que o usuário final deve ser capaz de adicionar um novo artigo ao banco de dados acaba de chegar.
Criar classe de teste (ArticleTests)
Para começar a escrever testes de unidade tSQLt, você precisa criar uma classe de teste adequada que pode ser facilmente criada criando um esquema no banco de dados em teste.
Crie o esquema ArticleTests (classe de teste) da seguinte maneira:
USE SQLDevArticlesV3;
GO
-- Creating unit test calss ArticleTests
CREATE SCHEMA [ArticleTests]
Authorization dbo
GO
EXECUTE sp_addextendedproperty @name='tSQLt.TestClass',@value=1,@level0type='SCHEMA',@level0name='ArticleTests'
Seja foco nos requisitos
A primeira etapa no desenvolvimento de banco de dados orientado a testes é apenas se concentrar em atender ao requisito apenas confiando em testes de unidade mais do que nos próprios objetos.
Isso significa que temos que criar um objeto de banco de dados potencial AddArticle.
Criar teste de unidade SQL para verificar a existência do objeto
O desenvolvimento de banco de dados orientado a teste exige primeiro escrever um teste de unidade para verificar se o objeto potencial existe ou não.
Escreva o primeiro teste de unidade para ver se o objeto existe ou não da seguinte maneira:
CREATE PROCEDURE ArticleTests.[test to check AddArticle exists]
AS
BEGIN
--Assemble
--Act
--Assert
EXEC tSQLt.AssertObjectExists @ObjectName = N'AddArticle'
END;
GO
Execute o teste de unidade para verificar a existência do objeto
Esta é a parte complicada que sabemos que o objeto não existe, então por que estamos executando o teste de unidade? A resposta é cumprir com o desenvolvimento de banco de dados orientado a testes, no qual os testes de unidade conduzem o processo e eles devem passar para prosseguir.
Execute todo o teste de unidade executando todos os testes de unidade para a classe de teste ArticleTests da seguinte maneira:
-- Run all unit tests related to ArticleTest test class
EXEC tsqlt.RunTestClass "ArticleTests"
É óbvio na saída da classe de teste que o teste de unidade para verificar a existência do objeto falhou:
Criar objeto de banco de dados (ArticleTests)
Agora crie o objeto de banco de dados como um stub, o que significa apenas criar um objeto de banco de dados com parâmetros, mas sem qualquer funcionalidade, porque estamos interessados apenas em criá-lo no momento.
Digite o seguinte código para criar o objeto:
-- Creating database object (stored procedure) AddArticle stub (placeholder)
CREATE PROCEDURE AddArticle (@Name VARCHAR(40),@Published_Date DATETIME2)
AS
BEGIN
SET NOCOUNT ON;
END
GO
Execute novamente o teste de unidade para verificar se o objeto existe
Depois de criar o stub de objeto, execute novamente a classe de teste de unidade:
-- Rerun ArticleTest test class EXEC tsqlt.RunTestClass "ArticleTests" |
Seu teste de unidade passou agora, então o objeto que deve atender ao requisito existe, no entanto, tenha em mente que isso não significa que o objeto necessariamente atende ao requisito de negócios.
Criar teste de unidade para verificar as funções do objeto corretamente
No desenvolvimento de banco de dados orientado a teste, o teste de unidade é escrito primeiro para verificar se o objeto funciona corretamente ou não, o que, por sua vez, aciona o objeto de banco de dados a ser desenvolvido para atender apenas à especificação.
A maneira recomendada de verificar as funções do objeto AddArticle corretamente é escrever o teste de unidade SQL que adiciona novo artigo ao banco de dados usando o objeto potencial e, em seguida, os resultados são comparados com os resultados esperados.
Escreva o teste de unidade para verificar se o objeto funciona corretamente da seguinte maneira:
--Create unit test to check AddArticle works
CREATE PROCEDURE [ArticleTests].[test to check AddArticle adds article to the table]
AS
-- Assemble
EXEC tSQLt.FakeTable @TableName='dbo.Article',@Identity=1 -- Fake Article table
Create TABLE [ArticleTests].[Expected] -- Create expected table
(
[ArticleId] INT NOT NULL,
[Title] VARCHAR(40) NOT NULL,
[Published_Date] DATETIME2 NOT NULL
)
INSERT INTO ArticleTests.Expected -- Insert data into exepcted table
(ArticleId,Title,Published_Date)
VALUES
(1,'Reporting Fundamentals','10 Nov 2018')
-- Act
EXEC dbo.AddArticle 'Reporting Fundamentals','10 Nov 2018' -- Run AddArticle procedure which adds new article to the Article table
SELECT * INTO ArticleTests.Actual FROM dbo.Article -- Put the records from Article table into Actual table
-- Assert (compare expected table with actual table results)
EXEC tSQLt.AssertEqualsTable @Expected='ArticleTests.Expected',@Actual='ArticleTests.Actual'
Execute testes de unidade para verificar se o objeto existe e funciona corretamente
Agora, a execução de todos os testes de unidade deve passar parcialmente porque o teste para verificar se o objeto funciona corretamente vai falhar.
-- Rerun ArticleTest test class
EXEC tsqlt.RunTestClass "ArticleTests"
Refatorar objetos e executar novamente testes de unidade
Modifique o procedimento armazenado AddArticle com a instrução insert correta, de modo que todos os testes de unidade sejam aprovados agora.
-- Alter database object (stored procedure) AddArticle to properly add new article
ALTER PROCEDURE AddArticle(@Title VARCHAR(40),@Published_Date DATETIME2)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO dbo.Article (Title, Published_Date)
VALUES
(@Title,@Published_Date)
END
GO
Execute os testes de unidade:
-- Run unit tests related to ArticleTests
EXEC tsqlt.RunTestClass "ArticleTests"
Parabéns, o fato de todos os testes de unidade terem passado agora garante que o objeto seja capaz de atender ao requisito de negócios para adicionar um novo artigo ao banco de dados agora.
Resumo
Depois de passar por este artigo e seguir o passo a passo, você se familiarizou com a metodologia de desenvolvimento de banco de dados orientada a testes, que não é apenas rica em recursos, mas também oferece muita flexibilidade para lidar com requisitos de negócios que variam de cenários simples a complexos.