node.js development workflow automation with grunt.js
DESCRIPTION
Slides for presentation I have at Hydrahack in Birmingham on 18th March 2014. http://hydrahack.co.uk/ http://talis.comTRANSCRIPT
Node.Js Development Workflow Automation With Grunt.Js
Nadeem ShabirHydrahack Birmingham18th March 2014
~ Paul Irish
“Your job as a developer isn’t to just develop, it’s to continually learn how to develop
better.”
Automating common tasks• code quality (jshint)
• beautifying (jsbeautifier)
• live reload (watch)
• Automated Testing
Grunt.jshttp://gruntjs.com
http://gulpjs.com
– Shaun Dunne ( https://medium.com/fear-and-coding )
“If you’re doing automation, you’re already doing something right. It’s not about how you
do it”
Grunt.js• Javascript based task runner
• automate repetitive tasks
• large ecosystem of plugins (2500+)
• easy to maintain
• simple to learn and use
ANT
GRUNT
Install
npm install -g grunt-cli cd <your_project_dir> npm install grunt --save-dev npm install grunt-contrib-jshint grunt-contrib-watch \ grunt-mocha-test grunt-jsbeautifier --save-dev
gruntfile.js
watch• runs predefined tasks when files change
• use patterns to indicate which files to watch
jshint• static code analysis tool
• detect errors & potential problems
• enforce team coding conventions
• every time we change a .js file
jsbeautify• reformats Javascript source code
• enforces code formatting conventions
• easier to read and understand
• every time we change a .js file
live reload• monitors changes in files
• preprocesses files as needed
• browser automatically reloads and shows your changes
• built into grunt-contrib-watch
Automated Testing
!~ Gerald Weinberg
Weinberg’s Second Law: !
“If builders built buildings the way programmers wrote programs, the first wood-
pecker that came along would destroy civilization”
Test Driven Development
BDD vs TDD• The gotcha with TDD is that too many developers focused on
the "How" when writing their unit tests, so they ended up with very brittle tests that did nothing more than confirm that the system does what it does.
• BDD provides a new vocabulary and thus focus for writing a unit test. Basically it is a feature driven approach to TDD.
~ Matt Wynne http://blog.mattwynne.net/2012/11/20/tdd-vs-bdd/
“BDD builds upon TDD by formalising the good habits of the best TDD practitioners”
Tools• mocha - (http://visionmedia.github.io/mocha/) BDD, TDD, QUnit
styles via interfaces
• should.js - (https://github.com/visionmedia/should.js/) expressive, readable, test framework agnostic, assertion library
• supertest - (https://github.com/visionmedia/supertest) Super-agent driven library for testing HTTP servers. E2E for apis.
• Protractor - (https://github.com/angular/protractor) E2E test framework for Angular apps
… caveat
• This is based on my personal experience and opinion - YMMV
• I’ve been known to change my mind ;-)
• … BUT these tools and techniques are being used on a lot of projects successfully.
Mocha• vs Jasmine - Jasmine is easier to get started –
great all-in-one test framework.
• Mocha is more flexible: you have to piece it together yourself. i.e. add an assertion framework, add a spy/mocking framework. Supports different styles of testing, lots of reporters (spec, xunit, nyan ;-) ) & disable tests
describe(“my test suite”, function(){!!! it(“should test something”, function(done){!! ! // do some assertions here!! ! // when your test completes call !! ! done();!! !! });!!! xit(“this test is skipped”, function(done){!! ! done();!! !! });!!});
Mocha - BDD
should.js• nice assertion library. There are lots of others
for example chai which is also very good.
• chainable language to construct assertions
• its api provides lots of assertion methods
• very easy to read
it(“should test something useful”, function(done){!! !! var colors = [‘red’, ‘white’, ‘blue’];!!! colors.should.include(‘red’);!! colors.should.not.include(‘yellow’);!! colors.length.should.equal(3);!! colors.should.be.an.instanceof(Array);!! !! done();!! !});!
calculator_test.js
models/calc.js
supertest• great way to test running http apis,
• provides assertions and expectations for http
• when combined with async, makes it easy to test a series of api calls
• easy to use and makes tests easy to read!
var request = require(“supertest”);!!it(“should return some json”, function(done){!! request(“http://localhost:3000”)! ! .get('/isbns/978000000000X/lists')! !.set('Accept', 'application/json')! !.expect('Content-Type', /json/)! !.expect(200)! !.end(function(err, res) {! !! if(err) return done(err);! !! ! ! res.body.should.xxxxx!! !! done();!! ! });! !});!
Protractor• Browser testing for Angular.js apps, built on
Webdriver.js
• uses selenium-webdriver, tests written in WebDriver API, communicates with Selenium to control browsers
• you can run tests locally using Selenium-Standalone
• you can run tests against any service that exposes Selenium Hub endpoint ( BrowserStack, SauceLabs)
Protractor
it('should greet the named user', function() {! browser.get('http://www.angularjs.org');! ! // find the element with ng-model matching 'yourName'! element(by.model('yourName')).sendKeys('Nadeem');! ! // find the <h1>Hello {{yourName}}!</h1> element.! var greeting = element(by.binding('yourName'));!! expect(greeting.getText()).toEqual('Hello Nadeem!');!});
chromeConf.js
Demo
E2E testing pitfalls• Use Selenium Standalone on local dev machines
• Use Continuous Integration to test range of browsers on different OS. Nightly builds etc.
• Use BrowserStack / SauceLabs / Other for CI, unless you have time/£ to set up you’re own infrastructure.
• Tunnelling to test local / internal deployments from those services can be slow / unreliable; avoid if possible …
github.com/kiyanwang/js-workflow-automation
engineering.talis.com
@talis facebook.com/talisgroup@talis facebook.com/talisgroup
+44 (0) 121 374 2740 !talis.com [email protected] !48 Frederick Street Birmingham B1 3HN