Todos los días vemos ciertos problemas a nivel de base de datos en los cuales es difícil dar seguimiento a los cambios que muchas personas hacen. Desafortunadamente no podemos dar seguimiento a todos los cambios que acontecen en nuestro ambiente.
Una manera fácil de poder dar seguimiento a algunos puntos en nuestra base de datos sería el manejo de UnitTest para nuestra base de datos.
Una de las herramientas que nos ayudan con este punto es la llamada tSQLt que es un framework gratuito que nos ayuda a generar casos para poder evaluar nuestras estructura, la existencia de nuestros objetos e incluso nuestras FK y UQ.
Este framework lo puedes descargar del siguiente link:
Vamos a ver algunos ejemplos de gran utilidad para poder hacer algunas validaciones en nuestras bases de datos.
Caso 1.
Verificar que nuestro objeto exista en la base de datos.
En la siguiente sintaxis nosotros verificamos que el objeto llamado tableTest exista en nuestra base de datos.
EXEC tSQLt.NewTestClass '[test.tableTestExists]';
GO
CREATE PROCEDURE [test.TableTest Exists].[Testing Exists tableTest Exists ]
AS
BEGIN
EXEC tSQLt.AssertObjectExists 'dbo.tableTest';
END;
GO
Caso 2.
Verificar estructura de tablas.
Con la siguiente estructura verificamos que nuestros campos sean los mismos que la tabla que evaluamos:
EXEC tSQLt.NewTestClass '[test.tableTestStructure]';
GO
CREATE PROCEDURE [test.tableTestStructure].[Testing tableTest Structure]
AS
BEGIN
IF OBJECT_ID('Expected') IS NOT NULL DROP TABLE Expected;
IF OBJECT_ID('Actual') IS NOT NULL DROP TABLE Actual;
SELECT TOP 1 * INTO Actual From dbo.tableTest
CREATE TABLE Expected (
CreatedBy NVARCHAR(25) NOT NULL,
CreatedOn DATETIME NOT NULL,
ModifiedBy NVARCHAR(25) NOT NULL,
ModifiedOn DATETIME NOT NULL,
RowVersion INT NOT NULL,
Code NVARCHAR(10) NOT NULL,
Name NVARCHAR(20) NOT NULL
);
INSERT INTO dbo.Actual (Code,Name,CreatedBy,CreatedOn,ModifiedBy,ModifiedOn,RowVersion) VALUES
('es','Spanish','SM','08/12/2014','','',0)
INSERT INTO dbo.Expected(Code,Name,CreatedBy,CreatedOn,ModifiedBy,ModifiedOn,RowVersion) VALUES
('es','Spanish','SM','08/12/2014','','',0)
------Assertion
EXEC tSQLt.AssertEqualsTable 'dbo.Expected','dbo.Actual'
END
GO
En ésta sintaxis la tabla Actual representa la estructura que tenemos actualmente en la base de datos, y la tabla Expected contiene una estructura que declaramos, la cual será verificada contra la Actual buscando algún cambio.
Caso 3.
Verificación de la UQ en nuestras tablas.
En la siguiente sintaxis tratamos de insertar un record duplicado, en éste caso tenemos una UQ que no permitirá que dos Code se repitan, la sintaxis es la siguiente:
EXEC tSQLt.NewTestClass '[test.tableTestConstrainUQ]';
GO
CREATE PROCEDURE [test.tableTestConstrainUQ].[TEST UQ_tableTestCode]
AS
BEGIN
EXEC tSQLt.FakeTable 'dbo.tableTest'
EXEC tSQLt.ApplyConstraint 'dbo.tableTest','UQ_tableTestCode'
DECLARE @ErrorMessage NVARCHAR(MAX); SET @ErrorMessage = '';
BEGIN TRY
INSERT INTO dbo.tableTest (Code,Name,CreatedBy,CreatedOn,ModifiedBy,ModifiedOn,RowVersion) VALUES
('es','Spanish','SM','08/12/2014','','',0)
INSERT INTO dbo.tableTest (Code,Name,CreatedBy,CreatedOn,ModifiedBy,ModifiedOn,RowVersion) VALUES
('es','Spanish','SM','08/12/2014','','',0)
END TRY
BEGIN CATCH
SET @ErrorMessage = ERROR_MESSAGE()
END CATCH
IF @ErrorMessage NOT LIKE '%UQ_tableTestCode%'
BEGIN
EXEC tSQLt.Fail 'Expected error message containing ''UQ_tableTestCode'' but got: ''',@ErrorMessage,'''!';
END
END
GO
Como podemos ver la sintaxis anterior trata de insertar un record con el mismo Code, de esta manera estamos probando que nuestra UQ funcione de manera correcta.
Cabe mencionar que en días pasados encontré otra herramienta que se compagina con tSQLt, es de la Compañía Red-Gate, esta herramienta está basada en test hechos con tSQLt, la diferencia que pude notar es la forma en la cual presenta los resultados, es más amigable al usuario.
Así se presenta en tSQLt los resultados:
—
Al final el resultado es el mismo, solo que para mi punto de vista preferiría hacerlo de manera GRATUITA si obtengo el mismo resultado y la cantidad de trabajo es la misma.
Aquí les dejo el link para que puedan jugar un poco con la herramienta de Red-Gate
http://www.red-gate.com/products/sql-development/sql-test/
Espero les sea de utilidad esta artículo, hasta la próxima.
Excelente post!
Me pregunto qué ventajas (además de hacer agnósticas las pruebas de persistencia) tiene hacer esto en comparación con usar un framework de testing como XUnit o NUnit y cómo se integrarian estas pruebas en un CI Server como Team City o Travis.
De igual manera, si el problema es dar seguimiento a los cambios, por qué no entrenar a tu equipo para realizar las migraciones correspondientes, ya sea manualmente o usando alguna herramienta como el FluentMigrator.
Saludos.
Hola Minoru, gracias por interesarte en éste artículo, con respecto a los equipo nosotros entrenamos a nuestra gente, pero siempre hay que dar seguimiento a los cambios que se hacen y siempre habrá errores, esta herramienta en un principio nos permite saber si todos los objetos que tenemos en nuestro repositorio fueron debidamente enviados a los servidores como punto primario, de ahí usamos esta herramienta para comprobar que una base de datos en blanco tenga las estructuras necesarias para poder cumplir con los requerimientos del sistema que manejamos.
El tSQLt en lo particular es una herramienta que estoy empezando a explotar, me gusta que puedes ejecutar tus scripts directamente en el SQL (lógicamente esto no se recomienda hacer en tu servidor de producción) y de primera mano saber lo que está fallando, lógicamente según los casos que hayas validado.
Al compararlo con la herramienta NUnit que es posiblemente más robusta me hace pensar que la diferencia fundamental es que el tSQLt fue hecha solo para SQL en cambio el NUnit abarca mas conceptos como testeo de DLL y demás cosas, al final del día, ésta es una herramienta más que podemos manejar para poder proteger nuestra base de datos antes de ser enviada a producción.
Thank you for sharing your thoughts. I truly appreciate your
efforts and I will be waiting for your further write
ups thank you once again.