Cloudibn News

Be updated with Technology

  • BIG Data & Analytics
  • CLOUD
  • Data Center
  • IOT
  • Machine Learning & AI
  • SECURITY
  • Blockchain
  • Virtualization
You are here: Home / CLOUD / AWS Velocity Series: Local development environment

AWS Velocity Series: Local development environment

February 8, 2017 by cbn Leave a Comment

The local development environment is where you make changes to the source code, edit configuration files, add images, and so on. You also want to run the app locally, execute the tests, and be able to debug your source code.

AWS Velocity: Local development environment

In this article you will learn how to setup a Node.js project from scratch with:

  • Unit tests to cover internal functionality
  • Code checks to get rid of typos and code smells early
  • Acceptance tests to verify the end-user behavior

The Node.js app will offer an HTTP API to compute factorials. The concepts can be applied to any other programming language.

AWS Velocity Cover

AWS Velocity Series

Most of our clients use AWS to reduce time-to-market following an agile approach. But AWS is only one part of the solution. In this article series, I show you how we help our clients to improve velocity: the time from idea to production. Discover all posts!

Let’s get started!

Setup project

You can follow step by step or get the full source code here: https://github.com/widdix/aws-velocity

First, create a folder for the new project. I assume that you use macOS or Linux running a terminal:

mkdir aws-velocity
cd aws-velocity/

Within the new project folder, create folders for your app, infrastructure, deploy scripts, and your acceptance tests.

mkdir app
mkdir infrastructure
mkdir deploy
mkdir acceptance

The project structure should look like this now:

tree ../aws-velocity/
#../aws-velocity/
#├── acceptance
#├── app
#├── deploy
#└── infrastructure
#4 directories, 0 files

Let’s develop the app next.

A simple app

Now you need a simple app that you can use as an example. The app will be based on Node.js but the concepts will apply to all other programming languages. If you don’t have Node.js installed, visit nodejs.org.

cd app/
mkdir test
mkdir lib

Now, create the app structure with the npm init tool. The tool will ask you a bunch of questions, make sure to answer them as I did:

npm init
# name: (app) factorial
# version: (1.0.0) 1.0.0
# description: Factorial as a Service
# entry point: (index.js) index.js
# test command: ./node_modules/.bin/jshint . && ./node_modules/.bin/mocha test/*.js
# git repository:
# keywords:
# author:
# license: (ISC)
# About to write to /Users/michael/Desktop/aws-velocity/app/package.json:
# {
# "name": "factorial",
# "version": "1.0.0",
# "description": "Factorial as a Service",
# "main": "index.js",
# "directories": {
# "test": "test"
# },
# "scripts": {
# "test": "jshint . && ./node_modules/.bin/mocha test/*.js"
# },
# "author": "",
# "license": "ISC"
# }
# Is this ok? (yes) yes

And you need to install a few dependencies. express is a popular web framework, jshint is a code quality tool, and mocha is a test framework:

npm install express@4.14.0 --save
npm install jshint@2.9.4 --save-dev
npm install mocha@3.2.0 --save-dev

jshint needs a little bit of configuration. Create a file .jshintrc with the following content:

app/.jshintrcGitHub
{
"esversion": 5,
"node": true
}

Create a file test/.jshintrc with the following content:

app/test/.jshintrcGitHub
{
"extends": "../.jshintrc",
"mocha": true
}

Create a file .jshintignore with the following content:

app/.jshintignoreGitHub
node_modules/**

Now the app structure is done. Let’s see if the test command works:

npm test
# > factorial@1.0.0 test /Users/michael/Desktop/aws-velocity/app
# > jshint . && ./node_modules/.bin/mocha test/*.js
#
# Warning: Could not find any test files matching pattern: test/*.js
# No test files found
# npm ERR! Test failed. See above for more details.

The tests fail because there are no tests. So let’s add some unit tests for the factorial implementation.

Create a file test/factorial.js with the following content. The structure of the file is determined by the test framework mocha. The important lines start with assert.equal. Those lines contain actual test conditions that the implementation must satisfy:

app/test/factorial.jsGitHub
'use strict';

var factorial = require('../lib/factorial.js');
var assert = require('assert');

describe('factorial', function() {
it('should fail for < 0', function() {
assert.throws(function() {
factorial(-1);
});
});
it('should return 1 for 0', function() {
assert.equal(factorial(0), 1);
});
it('should return 1 for 1', function() {
assert.equal(factorial(1), 1);
});
it('should return 2 for 2', function() {
assert.equal(factorial(2), 2);
});
it('should return 6 for 3', function() {
assert.equal(factorial(3), 6);
});
it('should return 24 for 4', function() {
assert.equal(factorial(4), 24);
});
it('should return 120 for 5', function() {
assert.equal(factorial(5), 120);
});
it('should return 87178291200 for 14', function() {
assert.equal(factorial(14), 87178291200);
});
it('should fail for > 14', function() {
assert.throws(function(){
factorial(15);
});
});
});

If you run npm test again, the test still fail because there is no implementation yet. Let’s change that.

Create a file lib/factorial.js with the following content. The factorial implementation is recursive:

app/lib/factorial.jsGitHub
'use strict';

function factorial(n) {
if (n === 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}

module.exports = factorial;

Let’s see if the tests pass now by running npm test.

Oh no, the implementation is missing some checks for edge cases. Change the file lib/factorial.js accordingly:

app/lib/factorial.jsGitHub
'use strict';

function factorial(n) {
if (n < 0) {
throw new Error('not defined for negative numbers');
}
if (n > 14) {
throw new Error('not implemented for large numbers');
}
if (n === 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}

module.exports = factorial;

Now, wire express up to offer a HTTP endpoint for factorial computation. Create a file index.js with the following content:

app/index.jsGitHub
'use strict';

var factorial = require('./lib/factorial.js');
var express = require('express');
var app = express();

app.get('/:n', function (req, res) {
var n = parseInt(req.params.n, 10);
if (n < 0 || n > 14) {
res.sendStatus(400);
} else {
res.send(factorial(n).toString());
}
});

var port = process.env.PORT || 3000;
app.listen(port, function () {
console.log('app listening on port ' + port);
});

You can now start the app locally:

node index.js
# app listening on port 3000

In another terminal, execute curl to make a HTTP request against your app:

curl http://localhost:3000/5
# 120

So far so good. It’s time to add an acceptance test.

cd ..
cd acceptance/

Now, create the acceptance test structure. The acceptance test is an independent application also using Node.js. The npm init command will setup the project. Make sure to configure it like I did:

npm init
# name: (acceptance) factorial-acceptance
# version: (1.0.0) 1.0.0
# description: Acceptance test for Factorial as a Service
# entry point: (spec.js)
# test command: ./node_modules/.bin/jshint .
# git repository:
# keywords:
# author:
# license: (ISC)
# About to write to /Users/michael/Desktop/aws-velocity/acceptance/package.json:
# {
# "name": "acceptance",
# "version": "1.0.0",
# "description": "",
# "main": "spec.js",
# "scripts": {
# "test": "jshint ."
# },
# "author": "",
# "license": "ISC"
# }
#Is this ok? (yes) yes

And again, you need to install a few dependencies. frisby helps us to test REST APIs, jasmine is yet another test framework, and jshint will ensure code quality:

npm install frisby@0.8.5 --save
npm install jasmine-node@1.14.5 --save
npm install jshint@2.9.4 --save-dev

jshint needs some configuration. Create a file .jshintrc with the following content:

acceptance/.jshintrcGitHub
{
"esversion": 5,
"node": true,
"jasmine": true
}

Create a file .jshintignore with the following content:

acceptance/.jshintignoreGitHub
node_modules/**

Now the app structure is created. Let’s see if the test command works:

npm test

Everything is okay. Now you need to implement the acceptance test.

Create a file factorial_spec.js (the file must end with _spec.js!) with the following content. The structure is determined by frisby, lines with a condition start with .expect:

acceptance/factorial_spec.jsGitHub
'use strict';

var frisby = require('frisby');

if (process.env.ENDPOINT === undefined) {
throw new Error('ENDPOINT environment variable missing');
}

frisby.create('/-1')
.get(process.env.ENDPOINT + '/-1')
.expectStatus(400)
.toss();

frisby.create('/0')
.get(process.env.ENDPOINT + '/0')
.expectStatus(200)
.expectBodyContains('1')
.toss();

frisby.create('/14')
.get(process.env.ENDPOINT + '/14')
.expectStatus(200)
.expectBodyContains('87178291200')
.toss();

frisby.create('/15')
.get(process.env.ENDPOINT + '/15')
.expectStatus(400)
.toss();

To execute the acceptance tests against your locally running app (if you stopped the app, run node index.js in a separate terminal), run:

ENDPOINT="http://localhost:3000" ./node_modules/.bin/jasmine-node .
#Finished in 0.083 seconds
#4 tests, 6 assertions, 0 failures, 0 skipped

The application is done. You have unit tests, and you also have acceptance tests. The Important differences between the two are:

  • Unit tests can run without spawning a web server
  • Unit tests ensure that the factorial function returns the correct values
  • Acceptance tests ensure that the REST API works as expected (e.g. as documented, or as it behaved before)

In the next article, you will learn how to setup the CI/CD pipeline for your new app.

Series

AWS Velocity Cover

  1. Set the assembly line up
  2. Local development environment (you are here)
  3. CI/CD Pipeline as Code
  4. Running your application
  5. EC2 based app
    a. Infrastructure
    b. CI/CD Pipeline
  6. Containerized ECS based app
    a. Infrastructure
    b. CI/CD Pipeline
  7. Serverless app
  8. Summary

You can find the source code on GitHub.

Share on FacebookShare on TwitterShare on LinkedinShare on Pinterest

Filed Under: CLOUD

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Archives

  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • October 2017
  • September 2017
  • August 2017
  • July 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • July 2016
  • June 2016
  • May 2016
  • April 2016
  • March 2016

Recent Posts

  • Featured on Tech Breakfast Podcast on Jan 15 2021 “Paul Braren: Eyes – Tesla Recall – Tedlexa – Mushrooms – Intel – EVs – Boeing”
  • CES 2021 wrap up: How enterprise tech makes all those smart toilets and robots possible
  • CES 2021 roundup: Tech trends business professionals should care about
  • VMblog 2021 Industry Experts Video Predictions Series – Episode 3
  • Entrust Acquires HyTrust, Expanding Encryption, Key Management and Security Posture Management for Virtualized and Multi-Cloud Environments

Recent Comments

  • +905443535397 on Announcing Cognitive Search: Azure Search + cognitive capabilities

Categories

  • Artificial intelligence
  • BIG Data & Analytics
  • BlockChain
  • CLOUD
  • Data Center
  • IOT
  • Machine Learning
  • SECURITY
  • Storage
  • Uncategorized
  • Virtualization

Categories

  • Artificial intelligence (39)
  • BIG Data & Analytics (33)
  • BlockChain (305)
  • CLOUD (1,568)
  • Data Center (10)
  • IOT (1,851)
  • Machine Learning (143)
  • SECURITY (291)
  • Storage (20)
  • Uncategorized (62)
  • Virtualization (755)

Subscribe Our Newsletter

0% Complete

Copyright © 2021 · News Pro Theme on Genesis Framework · WordPress · Log in