45
@matenadasdi Front-end Developer at Ustream

It's never too late to fight your legacy!

Embed Size (px)

DESCRIPTION

It's never too late to fight your legacy! https://speakerdeck.com/matenadasdi/its-never-too-late-to-fight-your-legacy At Ustream we feel the need of full coverage including unit testing and end-to-end testing and bringing our structured framework into play with continuous integration on the frontend side. My presentation provides insight into our first problems, tells where we are on this bumpy road, and what is our plan to maintain this state in the future.

Citation preview

Page 1: It's never too late to fight your legacy!

@matenadasdiFront-end Developer at Ustream

Page 2: It's never too late to fight your legacy!

Why we think in large scale

Page 3: It's never too late to fight your legacy!

over 80 million active visitors / month

391,273,889 viewer hours last year

Page 4: It's never too late to fight your legacy!

It’s never too late to fight your legacy

our front-end dev achievements from last year

Page 5: It's never too late to fight your legacy!

What is legacy?Legacy is not bad code

it’s old or just over-iterated.

Page 6: It's never too late to fight your legacy!

A long time ago in a galaxy far, far away...

Let’s take a look back in general

Page 7: It's never too late to fight your legacy!

An average javascript codebase 2-3 years ago

feature based classes (example Gallery.js)

no tests

low perf optimization (no tools)

app.Gallery = Class({ page: 0, ! init: function () { this.wrapper = $(‘.gallery’); this.content = this.wrapper.find(‘.content’); this.wrapper.on( ‘click’, ‘.pager’, this.onPagerClick.bind(this) ); ! new CustomSelect(‘.custom-select’); ! _qaq.push([‘_trackEvent’, ‘gallery’, ‘load’, ‘init’]; }, ! onPagerClick: function () { this.page++; this.getPageData(this.page); }, ! getPageData: function () { $.getJSON(‘/gallery.json’, this.onResponse.bind(this)); }, ! onResponse: function (resp) { this.content.html(resp.html); } });

Page 8: It's never too late to fight your legacy!

We all know that this approach didn't work in large scale

Page 9: It's never too late to fight your legacy!

It would be nice to drop everything but of course it’s not an option

SOUNDS FAMILIAR?

Page 10: It's never too late to fight your legacy!

This was exactly our situation at Ustream.

Page 11: It's never too late to fight your legacy!

× new re-designs and layouts nearly every year

× using History API started a transformation

× rapidly growing complexity on the client side

It got worse because…

Page 12: It's never too late to fight your legacy!

That’s enough!

We needed more Stability & Scalability

Main decision

in the browser too

Page 13: It's never too late to fight your legacy!

Ok! Let’s start testing…

Wait, what?!

We can’t?

First problem

Page 14: It's never too late to fight your legacy!

Why?

× No separation between logic and its representation

× Huge “all-in-one” feature based class system

!

Page 15: It's never too late to fight your legacy!

We needed a new structure

Workshops

Page 16: It's never too late to fight your legacy!

Not the framework, but the way of thinking

is what really matters

Page 17: It's never too late to fight your legacy!

Think in layers with responsibilities

Page 18: It's never too late to fight your legacy!

DATA MANIPULATION LAYER

× simple data proxy between source and UI

Logic

× observable data object

× planning to integrate

ES7 Object.observe()

https://github.com/Polymer/observe-js

Model

COMMUNICATION TYPES

UI LAYER

AJAX WebStorage Cookies Socket Ustream Flash APILongpoll Embeds

Page 19: It's never too late to fight your legacy!

Take a breath check where you are Create prototypes

Prototyping, search for possibilities

Page 20: It's never too late to fight your legacy!

Logics Models

DATASOURCE LAYER

Sync Socket (full-duplex)Async

DATA MANIPULATION LAYER

UI LAYER

AJAX WebStorage Cookies Socket Ustream Flash APILongpoll Embeds

Page 21: It's never too late to fight your legacy!

Logics

DATASOURCE LAYER

Sync SocketAsync

AJAX WebStorage Cookies Socket Ustream Flash APILongpoll Embeds

Models

Views

Controllers

DOM

manipulate

notify

set dataget

control

events

DATA MANIPULATION LAYER

Page 22: It's never too late to fight your legacy!

\o/

× We created a really small modularized base (under 10kB)

× There was no “first idea” problem anymore

× It was just the beginning! 10kB vs 600+ files

New structure specified

Page 23: It's never too late to fight your legacy!

Modules vs simple assignment

Esprima for code modification automation https://github.com/ariya/esprima

Refactor automation

to

Page 24: It's never too late to fight your legacy!

Continuous integration

× New features are developed in new style with tests

× Refactor & new tests in small packages by features

Integration started

Page 25: It's never too late to fight your legacy!

Unit testing is not enough

!Writing tests like there's no tomorrow

Page 26: It's never too late to fight your legacy!

Strive to reach full coverage in every field!

Page 27: It's never too late to fight your legacy!

× dependency injection with RequireJS

× mocking with Sinon and Squire

× for business logic and complex controllers

Our testing pyramid - Unit testing

mocha + + + PhantomJSSinon.jsUnit testing

Page 28: It's never too late to fight your legacy!

× Node.js based navigation scripting

× experiments with TrifleJS

× for view / controller testing

Casper.js + +PhantomJS SlimerJS

mocha + + + PhantomJSSinon.jsUnit testing

Functional testing

Our testing pyramid - Functional testing

Page 29: It's never too late to fight your legacy!

× we have a dedicated TA team for years

× hundreds of tests on every platform already

× testing complex features (payment, purchase flows, etc)

Casper.js + +PhantomJS SlimerJS

mocha + + + PhantomJSSinon.jsUnit testing

Functional testing

TA team selenium testing Selenium + Java

Our testing pyramid - TA selenium testing

Page 30: It's never too late to fight your legacy!

× manual QA team

× we support them with automated tools

Casper.js + +PhantomJS SlimerJS

mocha + + + PhantomJSSinon.jsUnit testing

Functional testing

TA team selenium testing Selenium + Java

Manual QA team UI testing tools & debugging tools

Our testing pyramid - manual QA testing

Page 31: It's never too late to fight your legacy!

Screenshot comparison tool

Page 32: It's never too late to fight your legacy!

Internal Chrome DevTools extension

Page 33: It's never too late to fight your legacy!

Create your own standards and rules

!

selector is not allowed here

undefined is not a function

‘index’ is not defined

your line is too long

Invalid number of arguments

Unused parameter

unresolved function

Standards & rules creation

Page 34: It's never too late to fight your legacy!

Unify your workflow with automation

Workflow automation

we use grunt

Page 35: It's never too late to fight your legacy!

Remind others to obey the new rules

https://www.flickr.com/photos/ericflexyourhead/5811251629

Page 36: It's never too late to fight your legacy!

Integrate into your CI tool

CI integration

Page 37: It's never too late to fight your legacy!

Check your style as early as possible use hooks

More code quality tools

Page 38: It's never too late to fight your legacy!

Do not forget semantics create your own plugins, use ESLint and Esprima

ESLint

Page 39: It's never too late to fight your legacy!

Measure code complexity

Plato:

grunt complexity report in Jenkins:

Page 40: It's never too late to fight your legacy!

Code coverage essential for unit testing

Karma + Istanbul + IDE integration:

Page 41: It's never too late to fight your legacy!

Performance is a feature!

Page 42: It's never too late to fight your legacy!

A lot of possibilities

× measuring Navigation Timing & Resource Timing API

× tracking memory allocation with Web Performance API

× WebPageTest API automation

× planning to create peak alerts

memory allocation navigation timing

Page 43: It's never too late to fight your legacy!

new Date();

This is where we are

× over 500+ files changed

× hundreds of unit tests & functional tests

× every important part is modularized

× we are ready for async module loading too

Page 44: It's never too late to fight your legacy!

and many more to come

Page 45: It's never too late to fight your legacy!

Thank you!@matenadasdi