Managing Node Environment When Testing On Travis And Locally

Seun Agbeye
CloudBoost
Published in
4 min readNov 14, 2017

--

I will be explaining how to set up the different environments for your node-express project using Sequelize as your ORM for testing both on Travis and locally.

Managing your node environment is very essential when your code leaves your local machine maybe for production or testing with any continuous integration tool like Travis.

These are the steps you need you to get going:

This is the folder structure to get this guide below working for you

--server
--dist
--src
--package.json
--.babelrc
-.env
-sequelizerc
-travis.yml
-coveralls.yml

The server folder house the server-side code, while the dist is the es5 code of your es6 code in the src folder, basically it will house the compiled version of your es6 code in the src folder

First Setup your database environment by renaming your config.json file to config.js

export default {development: {username: "root",password: "password",database: "more_recipes",host: "127.0.0.1",port: 5432,secret_key: process.env.SECRET_KEY,dialect: "postgres"},test: {username: "root",password: "password",database: "more_recipes_test",host: "127.0.0.1",port: 5432,secret_key: process.env.SECRET_KEY,dialect: "postgres"},production: {environment: "production"}}

To use the process.env.SECRET_KEY the config.json must be changed to config.js to use JavaScript expression in it and you need to install a package called ‘dotenv’ .

npm: npm install dotenv
yarn: yarn add dotenv

This package helps you set up environment variables easily. After installing the package you need to import it at the top of your entry point file which may be index.js, www, app.js, or whatever you called it. The snippet below will help you do the necessary importation.

Entry Point File

import config from 'dotenv';config.config()

Next is creating a ‘.env’ file.

.env File Example

DB_NAME=mydatabase
DB_USER=I am Seun
DB_PASS=This is my password
DB_PORT=5432
DB_HOST=Here is my host
SECRET_KEY=This is my secret key
/* Please avoid space between the identifier and value i.e DB_NAME = mydatabase
This might get interpreted an something else
*/

Index.js File In The Models Folder

import fs from 'fs';import path from 'path';import Sequelize from 'sequelize';import configJson from '../config/config'const basename = path.basename(__filename);const env = process.env.NODE_ENV || 'development'; // Use development if no environment is specifiedconst config = configJson[env];const db = {};console.log(env)let sequelize;if (config.environment === 'production') {
This block will run only on production and use the environment variable set in the .env file
// sequelize = new Sequelize(process.env[config.use_env_variable]);sequelize = new Sequelize(process.env.DB_NAME,process.env.DB_USER,process.env.DB_PASS,{host: process.env.DB_HOST,port: process.env.DB_PORT,dialect: 'postgres',dialectOption: {ssl: true,native: true},logging: true});} else {sequelize = new Sequelize(config.database, config.username, config.password, config);}fs.readdirSync(__dirname).filter(file => (file.indexOf('.') !== 0) &&(file !== basename) &&(file.slice(-3) === '.js')).forEach((file) => {const model = sequelize.import(path.join(__dirname, file));db[model.name] = model;});Object.keys(db).forEach((modelName) => {if (db[modelName].associate) {db[modelName].associate(db);}});db.sequelize = sequelize;db.Sequelize = Sequelize;export default db;

travis.yml File

language: node_jsnode_js:- "stable"install: npm installservices:- postgresqlenv:- NODE_ENV=testbefore_script:- psql -c 'create database more_recipes_test;' -U postgres- psql -c "CREATE USER root WITH PASSWORD 'password';" -U postgres- npm run build- sequelize db:migrate- sequelize db:seed:allscript: npm testafter_success: npm run coverage# after_success: npm run coverage

The ‘services’ command setup a database service on Travis, ‘more_recipe_test’ is the name I want to call my database, you can call this anything. ‘root’ is the user for my database and ‘password’ is my database password, you can change this to your own credentials. ‘npm run build’ helps build my code to es5, I’m using the build file because that's what it been run on the machine I host my code on for production I’m testing on that same build for assurance, yours can be different.

If you’ll be using build files, you will need to add this snippet to your package.json file

"scripts": {"test": "set NODE_ENV=test&& npm run build&& sequelize db:migrate:undo:all&& sequelize db:migrate&& sequelize db:seed:all&& nyc mocha ./server/src/test/test.js --compilers js:babel-core/register --exit","babel-node": "babel-node ./server/src/index.js --presets=env","startDev": "nodemon --exec npm run babel-node -- ./server/src/index.js","build": "babel server/src -d server/dist","heroku-postbuild": "npm run build","start": "node server/dist/index.js","coverage": "nyc report --reporter=text-lcov | coveralls","coveralls": "nyc npm test&& nyc report --reporter=text-lcov | coveralls"},

run this command to get the necessary dependency needed for the scripts above to run

npm install babel-cli babel-core nyc coveralls nodemon mocha or yarn add babel-cli babel-core nyc coveralls nodemon mocha

The startDev can be used to run your server on development mode you can omit this if you use another package for running your development server

We need to make some little changes to the sequelizerc file to have different paths for our production, development, and testing codes, without this the test will fail because it's going to make use of the same path for all environments.

sequelizerc File

if (process.env != 'production'){
module.exports = {
"config": path.resolve('./server/src/config', 'config.js'),
"models-path": path.resolve('./server/src/models'),
"seeders-path": path.resolve('./server/src/seeders'),
"migrations-path": path.resolve('./server/src/migrations')
};
}
module.exports = {
"config": path.resolve('./server/dist/config', 'config.js'),
"models-path": path.resolve('./server/dist/models'),
"seeders-path": path.resolve('./server/dist/seeders'),
"migrations-path": path.resolve('./server/dist/migrations')
};

The above changes will get your testing passing on Travis and locally.

If this was helpful a clap from you shows appreciation and if you have any issues, I’m available on Facebook, you can send me a message and I will get back you back.

Thank you.

--

--