Esse curso poderia mostrar como separar um banco de dados só pra teste, enquanto temos outro banco para desenvolvimento. Como fazer isso?
Esse curso poderia mostrar como separar um banco de dados só pra teste, enquanto temos outro banco para desenvolvimento. Como fazer isso?
Olá, Luidi! Joia?
Essa é uma prática comum e recomendada para evitar que dados de teste interfiram no ambiente de desenvolvimento ou produção. Vou te explicar como você pode fazer isso.
Configuração de bancos de dados separados: a primeira coisa que você precisa fazer é configurar dois bancos de dados diferentes. Um será usado para desenvolvimento e o outro para testes. Isso pode ser feito criando dois arquivos de configuração, por exemplo, config.development.js e config.test.js, cada um apontando para o respectivo banco de dados.
Utilização de variáveis de ambiente: uma prática comum é utilizar variáveis de ambiente para definir qual banco de dados deve ser usado. Por exemplo, você pode ter uma variável NODE_ENV que determina se o ambiente é de desenvolvimento ou de teste. Com isso, seu código pode carregar a configuração correta com base no valor dessa variável.
Exemplo prático:
const config = {
development: {
client: 'sqlite3',
connection: {
filename: './dev.sqlite3'
}
},
test: {
client: 'sqlite3',
connection: {
filename: './test.sqlite3'
}
}
};
module.exports = config[process.env.NODE_ENV || 'development'];
NODE_ENV=test npm run test
Uso de bibliotecas de teste: algumas bibliotecas de teste, como o Jest, permitem configurar scripts de setup e teardown, que podem ser usados para criar e limpar o banco de dados de teste antes e depois de cada execução de teste.
Ao seguir essas etapas, você conseguirá manter seus ambientes de desenvolvimento e teste separados, garantindo que os dados de teste não interfiram no seu trabalho de desenvolvimento.
Espero ter ajudado e bons estudos!
Esse teste abaixo é um teste de integração. Embora alguns chamam o fluxo completo de E2E, tecnicamente ele ainda é de integração porque estamos isolados no ecossistema do back-end.
describe('Testando a rota login (POST)', () => {
it('O login deve possuir um email e senha para se autenticar', async () => {
const loginMock = {
email: 'raphael@teste.com.br',
};
await request(servidor)
.post('/login')
.send(loginMock)
.expect(500)
.expect('"A senha de usuario é obrigatório."');
});
O teste abaixo é chamado de Teste de Integração focado em persistência (muitas vezes chamado apenas de teste de banco de dados).
describe('Testando configDB', () => {
it('Teste de conexão com o banco de dados', async () => {
const autorMock = {
nome: 'Luana',
nacionalidade: 'Brasileira',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
};
const autorSalvo = await db('autores').insert(autorMock)
.then((retorno) => db('autores')
.where('id', retorno[0]))
.then((autorSelecionado) => autorSelecionado[0]);
expect(autorSalvo.nome).toBe(autorMock.nome);
await db('autores').where({ id: autorSalvo.id }).del();
});
});
A minha dúvida é se eu crio um banco de teste para esses 2 testes ou teria que criar um banco de testes chamdo E2E para o primeiro teste, pois alguns o chamam assim apesar de não estar tecnicamente correto. Pois já vi dizer q para os testes E2E cria um banco separado, mas daí seria o E2E verdadeiro e não esse q alguns chamam assim?
Oi, Luidi!
Use o mesmo banco de testes para os dois cenários (rota /login com supertest e teste direto no db). O nome “E2E” não muda a estratégia de banco neste ponto: o que manda é isolar do banco de desenvolvimento e garantir previsibilidade nos testes. Resolva fazendo o seguinte, direto ao ponto:
./database/test.sqlite3 ou um schema/DB separado no Postgres/MySQL).NODE_ENV=test e sempre aponte para o banco de testes quando rodar os testes.Ajuste seu código assim (Knex + SQLite, no mesmo estilo do curso):
// knexfile.js
module.exports = {
development: {
client: 'sqlite3',
connection: { filename: './database/dev.sqlite3' },
useNullAsDefault: true,
migrations: { directory: './database/migrations' },
},
test: {
client: 'sqlite3',
connection: { filename: './database/test.sqlite3' },
useNullAsDefault: true,
migrations: { directory: './database/migrations' },
},
};
// src/database/index.js
const knex = require('knex');
const knexfile = require('../../knexfile');
const env = process.env.NODE_ENV || 'development';
const db = knex(knexfile[env]);
module.exports = db;
No package.json, rode testes sempre com NODE_ENV=test:
{
"scripts": {
"test": "NODE_ENV=test jest --runInBand"
}
}
E garanta migrations + limpeza no ciclo de testes. Um jeito objetivo com Jest:
// test/setup.js
const db = require('../src/database');
beforeAll(async () => {
await db.migrate.latest(); // aplica migrations no banco de teste
});
beforeEach(async () => {
// limpe as tabelas que seus testes usam (ordem importa por FK)
await db('autores').del();
await db('usuarios').del();
});
afterAll(async () => {
await db.destroy();
});
// jest.config.js
module.exports = {
setupFilesAfterEnv: ['<rootDir>/test/setup.js'],
testEnvironment: 'node',
};
Com isso:
/login (fluxo HTTP) e seu teste direto no db (persistência) ficam isolados no mesmo banco de teste.Fico à disposição.