Let's talk about software quality

Does quality matter?

If you need to
go to the metro

Need a skate?

A car?

A truck?

A spaceship?

If your company needs to move very expensive goods?

The problem

The business is extremely frustrated with

engineering’s inability to deliver features rapidly and reliably.

Slow delivery
Buggy software releases
Poor scalability

Some organizations have difficulty eliminating technical debt because past attempts were too ambitious and didn’t provide much benefit.
As a result, the business becomes reluctant to invest in further clean up efforts.

The Law of Holes states that
"if you find yourself in a hole, stop digging"

"Any organization that designs a system (defined more broadly here than just information systems) will inevitably produce a design whose structure is a copy of the organization's communication structure."

CHANGE

states of change

The reliance on manual testing isn’t because of a lack of tooling and frameworks. For

example, JUnit, which is a popular Java testing framework, was first released in 1998.

The reason for lack of automated tests is mostly cultural: "testing is QA’s job", "it’s

not the best use of a developers’s time", etc. It also doesn’t help that developing a fast

running, yet effective, maintainable test suite is challenging. Also, a typical large

monolithic application is extremely difficult to test.

Since we don’t have unlimited budget for

development and testing, we want to focus on writing tests that have small scope

without compromising the effectiveness of the test suite.

Silos and pairing

Time to market

Profit

Why architecture matters?

You can deliver a lot of features

without software quality

You'll miss all the ilities

Scalability

Maintainability

Testability

Extensibility

Availability

https://en.wikipedia.org/wiki/List_of_system_quality_attributes

Understandability

Durability

Manageability

...

Sample

The importance of a well defined backlog

Will you build a factory, hire all the engineers and pieces without knowing what to build?

Tech debt

https://dzone.com/articles/measuring-technical-debt

Sample

Sample

Lets use FizzBuzz as your company business goals

Sample

System.out.println(1)

System.out.println(2)

System.out.println(FIZZ)

System.out.println(4)

System.out.println(BUZZ)

System.out.println(6)

Sample

System.out.println(1)

System.out.println(2)

System.out.println(FIZZ)

System.out.println(4)

System.out.println(BUZZ)

System.out.println(6)

Destructuring and spread

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

Spread & Destructuring

[a, b] = [10, 20];

console.log(a);
// expected output: 10

console.log(b);
// expected output: 20

[a, b, ...rest] = [10, 20, 30, 40, 50];

console.log(rest);
// expected output: [30,40,50]
var o = {p: 42, q: true};
var {p, q} = o;

console.log(p); // 42
console.log(q); // true

Spread

const person = { name: 'David Walsh', gender: 'Male' };
const tools = { computer: 'Mac', editor: 'Atom' };

const summary = {...person, ...tools};
/*
Object {
  "computer": "Mac",
  "editor": "Atom",
  "gender": "Male",
  "name": "David Walsh",
}
*/

Destructuring

function drawES6Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
  console.log(size, cords, radius);
  // do some chart drawing
}

drawES6Chart({
  cords: {x: 18, y: 30},
  radius: 30
});

drawES6Chart()
function drawES5Chart(options) {
  options = options === undefined ? {} : options;
  var size = options.size === undefined ? 'big' : options.size;
  var cords = options.cords === undefined ? {x: 0, y: 0} : options.cords;
  var radius = options.radius === undefined ? 25 : options.radius;
  console.log(size, cords, radius);
}

drawES5Chart({
  cords: {x: 18, y: 30},
  radius: 30
});

Destructuring

var metadata = {
    title: 'Scratchpad',
    translations: [
       {
        locale: 'de',
        localization_tags: [],
        last_edit: '2014-04-14T08:43:37',
        url: '/de/docs/Tools/Scratchpad',
        title: 'JavaScript-Umgebung'
       }
    ],
    url: '/en-US/docs/Tools/Scratchpad'
};

var {title: englishTitle, translations: [{title: localeTitle}]} = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle);  // "JavaScript-Umgebung"

Destructuring

var people = [
  {
    name: 'Mike Smith',
    family: {
      mother: 'Jane Smith',
      father: 'Harry Smith',
      sister: 'Samantha Smith'
    },
    age: 35
  },
  {
    name: 'Tom Jones',
    family: {
      mother: 'Norah Jones',
      father: 'Richard Jones',
      brother: 'Howard Jones'
    },
    age: 25
  }
];

for (var {name: n, family: {father: f}} of people) {
  console.log('Name: ' + n + ', Father: ' + f);
}

Iterators generators & iterables

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

Iterators

function makeIterator(array) {
    var nextIndex = 0;
    
    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
}
var it = makeIterator(['yo', 'ya']);
console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done);  // true

Generators *

function* idMaker() {
  var index = 0;
  while(true)
    yield index++;
}

var gen = idMaker();

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
// ...

Iterables

var myIterable = {};
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};

for (let value of myIterable) { 
    console.log(value); 
}

Unit testing

mocha

npm install mocha --save-dev
var assert = require('assert');

describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1',() => {
      assert.equal([1,2,3].indexOf(4), -1);
    });
  });
});

test script

{
  "name": "myawesomeapp",
  "version": "1.0.0",
  "description": "my awesome app",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "mocha test/* --recursive",
    "debug": "node --inspect-brk index.js"
  },
  "keywords": [
    "rest",
    "mongodb"
  ],
  "author": "alex",
  "license": "ISC",
  "dependencies": {
    "handlebars": "^4.0.11",
    "hapi": "^17.5.1",
    "mongodb": "^3.0.10",
    "vision": "^5.3.2"
  },
  "devDependencies": {
    "mocha": "^5.2.0"
  }
}

coverage

{
  "name": "myawesomeapp",
  "version": "1.0.0",
  "description": "my awesome app",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "nyc mocha test/* --recursive",
    "debug": "node --inspect-brk index.js"
  },
  "keywords": [
    "rest",
    "mongodb"
  ],
  "author": "alex",
  "license": "ISC",
  "dependencies": {
    ...
  },
  "devDependencies": {
    "mocha": "^5.2.0",
    "nyc": "^12.0.2"
  }
}
npm install nyc --save-dev

Refactor! To MVC

Refactor! To MVC


server.route(PeopleController.getPeople)

server.route(PeopleController.getPerson)

server.route(PeopleController.renderPerson)
server.route({
    method: 'GET',
    path: '/people',
    handler: (request) => {
        return Db.getPeople()
    }
})

server.route({
    method: 'GET',
    path: '/people/{name}',
    handler: (request) => {
        return Db.getPerson(request.params.name)
    }
})

server.route({
    method: 'GET',
    path: '/render/people/{name}',
    handler: async (request, h) => {
        const person = await Db.getPerson(request.params.name)

        return h.view('person', {
            message: 'Hello Handlebars!',
            person: person
        });
    }
})

Questions?

Homework

  • Play around with this (promises and =>)
  • Understand module.exports
  • Allow insertion of people REST
  • Form to perform insert with body
  • Go to MDN and node website!

Lets talk about software quality

By Alejandro Vidal Rodriguez

Lets talk about software quality

  • 23