SlideShare a Scribd company logo
Mehdi Valikhani
Software Engineer at AutopilotHQ
06 / 02 / 2017 | React Sydney Meetup
TDD: Develop,
refactor and
release with
confidence
“Worried that TDD
will slow down your
programmers?
Don't. They
probably need
slowing down.”
— J. B. Rainsberger
Writing
Testable Code
I.
Avoiding big and multi-purpose
units of code
(Functions, Classes, Components)
II.
Developing small and
focused units of code
III.
Separation of concerns
IV.
Using global objects
CAUTION: OVER-ENGINEERING TRAP AHEAD
Be careful when breaking down big components to
multiple small ones.
8
Writing Testable Code: Caution
TDD Principles
I.
Don’t test behaviour
of dependencies
(Both internal and external)
II.
Don’t integrate with internals
of a unit of code
(Components, Functions, Classes)
III.
Tests should be
execution-order agnostic
IV.
Tests should be
independent
V.
Tests should not have
side effects
VI.
Feedback
VII.
Focused Tests
VIII.
Consistency
IX.
Don’t be DRY
X.
Iterate, Review,
Improve
XI.
Test Code is Untested
Unit Tests
I.
 Component Internals
Don’t test internals of a component
— Example <UserProfile /> component
class UserProfile extends React.Component {
    _pathToAvatar(userId) {
        return `my-cdn.com/users/${userId}/avatar-320.png`;
    }
    render() {
        return (
            <div className=“user”>
                <h3 className=“user__name”>{this.props.name}</h3>
                <img 
                    className=“user__avatar” 
                    src=`${this._pathToAvatar(this.props.id)}` 
                />
           </div>
        );
    }
}
23
Unit Tests: Component Internals
— Bad Test
it(‘_pathToAvatar() returns correct path for given user id’, () => {
    const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);
    const subject = userProfile.instance()._pathToAvatar;
    const result = subject(123);
    expect(result).to.equal('my-cdn.com/users/123/avatar-320.png');
});
24
Unit Tests: Component Internals
— Bad Test
it(‘_pathToAvatar() returns correct path for given user id’, () => {
    const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);
    const subject = userProfile.instance()._pathToAvatar;
    const result = subject(123);
    expect(result).to.equal('my-cdn.com/users/123/avatar-320.png');
});
— Good Test
it(‘rendered image points to correct asset’, () => {
    const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);
    const subject = userProfile.find(‘.user__avatar’);
    const result = subject.prop(’src');
    expect(result).to.equal('my-cdn.com/users/123/avatar-320.png');
});
25
Unit Tests: Component Internals
II.
 Limit Your Implementation
Knowledge
— Example <Avatar /> component
const Avatar = ({ className, path }) => {
    const classes = classNames(‘avatar’, className);
    return (
        <img src={path} className={classes} />
    );
}
27
Unit Tests:  Limit Your Implementation Knowledge
— Example <UserProfile /> component
class UserProfile extends React.Component {
    _pathToAvatar(userId) {
        return `my-cdn.com/users/${userId}/avatar-320.png`;
    }
    render() {
        return (
            <div className=“user”>
                <h3 className=“user__name”>{this.props.name}</h3>
                <Avatar 
                    className=“user__avatar” 
                    path=`${this._pathToAvatar(this.props.id)}` 
                />
           </div>
        );
    }
}
28
Unit Tests:  Limit Your Implementation Knowledge
— Bad Test
it(‘rendered image points to correct asset’, () => {
    const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);
    const subject = userProfile.find(‘.icon’);
    const result = subject.prop(’src');
    expect(result).to.equal('my-cdn.com/users/123/avatar-320.png');
});
29
Unit Tests:  Limit Your Implementation Knowledge
— Bad Test
it(‘rendered image points to correct asset’, () => {
    const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);
    const subject = userProfile.find(‘.icon’);
    const result = subject.prop(’src');
    expect(result).to.equal('my-cdn.com/users/123/avatar-320.png');
});
— Good Test
it(‘rendered image points to correct asset’, () => {
    const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);
    const subject = userProfile.find(Avatar);
    const result = subject.prop(’path');
    expect(result).to.equal('my-cdn.com/users/123/avatar-320.png');
});
30
Unit Tests:  Limit Your Implementation Knowledge
III.
Test Structure
IV.
Host-agnostic Tests
TOOLS
enzyme
chai
mocha
33
Unit Tests: Tools
Snapshot
Tests
Problems with snapshot testing
35
Snapshot Tests
1. Validation of the “gold master” snapshot is manual and should be
done by developer
2. Unlike unit tests, snapshot tests don’t provide specific guidance for
what the original developer expected beyond the “actual behaviour”
3. They’re often fragile and generate lots of false negatives
Best Practices
36
Snapshot Tests
1. Well-formatted snapshots
2. Proper diff logs
3. Skip composed components
— Example
import React from 'react';
import { shallow } from 'enzyme';
import { expect } from 'chai';
import generateSubtree from 'enzyme-to-json';
import Button from './button';
describe(‘<Button />’, () => {
    it(‘Generated markup matches golden master’, function test() {
        const subject = shallow(
            <Button size=“small” color=“blue” icon=“save” text=“Save" />
        );
        const result = generateSubtree(subject);
        expect(result).to.matchSnapshot(
`${this.test.file}.snap`, 
this.test.title);
    });
});
37
Snapshot Tests
TOOLS
enzyme-to-json
chai-jest-snapshot
38
Snapshot Tests: Tools
Visual
Regression
Tests
I.
Test “widgets”, not
individual components
II.
Do not test multiple
“widgets” together
III.
Mock Data
IV.
Comparison Tool
TOOLS
webdriver.io
wdio-visual-regression-service
44
Visual Regression Tests: Comparison Tool: Tests
Tips
I.
Well-structured Bug Backlog
Bug Backlog Insights
47
Tips: Well-structured Bug Backlog
1. Identify missing tests
2. Improve code-review processes
3. Improve task spec
4. Training sessions
5. Pair programming
II.
Opportunities from
Fixing Bugs
Opportunities from Fixing Bugs
49
Tips: Opportunities from Fixing Bugs
1. Re-evaluate code readability
2. Investigate source of bug
3. Re-evaluate test readability
4. Re-evaluate existing test’s behaviour
Questions?
Thank You!
You can reach me at:
✉ hi@mv.id.au
@mehdivk

More Related Content

ODP
Grails unit testing
PDF
Unit test-using-spock in Grails
PPTX
Grails Spock Testing
ODP
Android Test Driven Development
PDF
Developer Tests - Things to Know (Vilnius JUG)
PPTX
UnitTestingBasics
PPT
Unit testing with java
PDF
Better Code through Lint and Checkstyle
Grails unit testing
Unit test-using-spock in Grails
Grails Spock Testing
Android Test Driven Development
Developer Tests - Things to Know (Vilnius JUG)
UnitTestingBasics
Unit testing with java
Better Code through Lint and Checkstyle

What's hot (20)

PDF
Working Effectively with Legacy Code
PDF
Migrating from Struts 1 to Struts 2
ODP
Good Practices On Test Automation
ODP
Testing In Java
PDF
Testability
PDF
Working Effectively with Legacy Code: Lessons in Practice
PPTX
Battle of The Mocking Frameworks
PPTX
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
PDF
Testing, Learning and Professionalism — 20171214
PPTX
Dusan Lukic Magento 2 Integration Tests Meet Magento Serbia 2016
PPSX
PDF
Devday2016 real unittestingwithmockframework-phatvu
PPTX
JUNit Presentation
PDF
PPTX
Please Behave Yourself: BDD and automating Eclipse RCP applications using JBe...
PDF
Test driven development - JUnit basics and best practices
PPT
Simple Unit Testing With Netbeans 6.1
PPTX
Junit4&testng presentation
PDF
Efficient JavaScript Unit Testing, May 2012
ODP
Testing in-groovy
Working Effectively with Legacy Code
Migrating from Struts 1 to Struts 2
Good Practices On Test Automation
Testing In Java
Testability
Working Effectively with Legacy Code: Lessons in Practice
Battle of The Mocking Frameworks
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
Testing, Learning and Professionalism — 20171214
Dusan Lukic Magento 2 Integration Tests Meet Magento Serbia 2016
Devday2016 real unittestingwithmockframework-phatvu
JUNit Presentation
Please Behave Yourself: BDD and automating Eclipse RCP applications using JBe...
Test driven development - JUnit basics and best practices
Simple Unit Testing With Netbeans 6.1
Junit4&testng presentation
Efficient JavaScript Unit Testing, May 2012
Testing in-groovy
Ad

Viewers also liked (20)

PDF
CoffeeScript, An Introduction for Nodejs developers
PPTX
Modular development in Node.js
PDF
MongoDB Database Replication
PDF
Catalogo de productos PROIPLAS
DOCX
Actividad 1.3 Corrientes Económicas
PDF
Sistema economico
DOCX
Actividad 1.2 modelos economicos
PDF
Revista el universo juridico
DOCX
Ficha de inscrição: Workshop Reino Unido
PDF
Presentación corporativa IDT Ingeniería
PDF
Gestion de stress
PPTX
El renacimiento (arquitectura, pintura y escultura)
PDF
2016-06 France Car Sales Opel June 2016
PPTX
Arismore - Réussir la transition vers la continuous Architecture
PPTX
Product Strategy of toyota
PDF
Webinar Template
PPTX
Planet of love-story for young children
DOCX
Escuelas economistas
PPTX
Hacia un nuevo tipo de relaciones Peru-China: El tren bioceanico Peru Brasil
PDF
Equipment India Article.Dec 2016.
CoffeeScript, An Introduction for Nodejs developers
Modular development in Node.js
MongoDB Database Replication
Catalogo de productos PROIPLAS
Actividad 1.3 Corrientes Económicas
Sistema economico
Actividad 1.2 modelos economicos
Revista el universo juridico
Ficha de inscrição: Workshop Reino Unido
Presentación corporativa IDT Ingeniería
Gestion de stress
El renacimiento (arquitectura, pintura y escultura)
2016-06 France Car Sales Opel June 2016
Arismore - Réussir la transition vers la continuous Architecture
Product Strategy of toyota
Webinar Template
Planet of love-story for young children
Escuelas economistas
Hacia un nuevo tipo de relaciones Peru-China: El tren bioceanico Peru Brasil
Equipment India Article.Dec 2016.
Ad

Similar to TDD: Develop, Refactor and Release With Confidence (20)

PDF
Don't let your tests slow you down
PDF
The Many Ways to Test Your React App
PDF
An existential guide to testing React UIs
PDF
Functional Testing for React Native Apps
ODP
Writing useful automated tests for the single page applications you build
PDF
Workshop 23: ReactJS, React & Redux testing
PDF
How to go about testing in React?
PPTX
Test driven development with react
PDF
Никита Галкин "Testing in Frontend World"
PDF
An Introduction to the World of Testing for Front-End Developers
PDF
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
PDF
Five steps towards your testing dream
PDF
Testing in FrontEnd World by Nikita Galkin
PDF
Intro To JavaScript Unit Testing - Ran Mizrahi
PDF
Test driven development and react js application go hand in hand
PDF
Intro to JavaScript Testing
PPTX
Testing of React JS app
PDF
The three layers of testing
PDF
ES3-2020-06 Test Driven Development (TDD)
PDF
Vuejs testing
Don't let your tests slow you down
The Many Ways to Test Your React App
An existential guide to testing React UIs
Functional Testing for React Native Apps
Writing useful automated tests for the single page applications you build
Workshop 23: ReactJS, React & Redux testing
How to go about testing in React?
Test driven development with react
Никита Галкин "Testing in Frontend World"
An Introduction to the World of Testing for Front-End Developers
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
Five steps towards your testing dream
Testing in FrontEnd World by Nikita Galkin
Intro To JavaScript Unit Testing - Ran Mizrahi
Test driven development and react js application go hand in hand
Intro to JavaScript Testing
Testing of React JS app
The three layers of testing
ES3-2020-06 Test Driven Development (TDD)
Vuejs testing

Recently uploaded (20)

PDF
null (2) bgfbg bfgb bfgb fbfg bfbgf b.pdf
PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
PDF
A SYSTEMATIC REVIEW OF APPLICATIONS IN FRAUD DETECTION
PPTX
additive manufacturing of ss316l using mig welding
PDF
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
PPTX
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
PDF
PPT on Performance Review to get promotions
PPT
Introduction, IoT Design Methodology, Case Study on IoT System for Weather Mo...
PPTX
Safety Seminar civil to be ensured for safe working.
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PDF
III.4.1.2_The_Space_Environment.p pdffdf
PDF
Level 2 – IBM Data and AI Fundamentals (1)_v1.1.PDF
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
PPTX
Fundamentals of Mechanical Engineering.pptx
PPTX
Geodesy 1.pptx...............................................
PPT
Mechanical Engineering MATERIALS Selection
DOCX
573137875-Attendance-Management-System-original
PDF
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
PDF
Well-logging-methods_new................
null (2) bgfbg bfgb bfgb fbfg bfbgf b.pdf
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
A SYSTEMATIC REVIEW OF APPLICATIONS IN FRAUD DETECTION
additive manufacturing of ss316l using mig welding
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
PPT on Performance Review to get promotions
Introduction, IoT Design Methodology, Case Study on IoT System for Weather Mo...
Safety Seminar civil to be ensured for safe working.
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
III.4.1.2_The_Space_Environment.p pdffdf
Level 2 – IBM Data and AI Fundamentals (1)_v1.1.PDF
UNIT-1 - COAL BASED THERMAL POWER PLANTS
Fundamentals of Mechanical Engineering.pptx
Geodesy 1.pptx...............................................
Mechanical Engineering MATERIALS Selection
573137875-Attendance-Management-System-original
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
Well-logging-methods_new................

TDD: Develop, Refactor and Release With Confidence

  • 1. Mehdi Valikhani Software Engineer at AutopilotHQ 06 / 02 / 2017 | React Sydney Meetup TDD: Develop, refactor and release with confidence
  • 2. “Worried that TDD will slow down your programmers? Don't. They probably need slowing down.” — J. B. Rainsberger
  • 4. I. Avoiding big and multi-purpose units of code (Functions, Classes, Components)
  • 8. CAUTION: OVER-ENGINEERING TRAP AHEAD Be careful when breaking down big components to multiple small ones. 8 Writing Testable Code: Caution
  • 10. I. Don’t test behaviour of dependencies (Both internal and external)
  • 11. II. Don’t integrate with internals of a unit of code (Components, Functions, Classes)
  • 14. V. Tests should not have side effects
  • 20. XI. Test Code is Untested
  • 22. I.  Component Internals Don’t test internals of a component
  • 23. — Example <UserProfile /> component class UserProfile extends React.Component {     _pathToAvatar(userId) {         return `my-cdn.com/users/${userId}/avatar-320.png`;     }     render() {         return (             <div className=“user”>                 <h3 className=“user__name”>{this.props.name}</h3>                 <img                      className=“user__avatar”                      src=`${this._pathToAvatar(this.props.id)}`                  />            </div>         );     } } 23 Unit Tests: Component Internals
  • 24. — Bad Test it(‘_pathToAvatar() returns correct path for given user id’, () => {     const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);     const subject = userProfile.instance()._pathToAvatar;     const result = subject(123);     expect(result).to.equal('my-cdn.com/users/123/avatar-320.png'); }); 24 Unit Tests: Component Internals
  • 25. — Bad Test it(‘_pathToAvatar() returns correct path for given user id’, () => {     const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);     const subject = userProfile.instance()._pathToAvatar;     const result = subject(123);     expect(result).to.equal('my-cdn.com/users/123/avatar-320.png'); }); — Good Test it(‘rendered image points to correct asset’, () => {     const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);     const subject = userProfile.find(‘.user__avatar’);     const result = subject.prop(’src');     expect(result).to.equal('my-cdn.com/users/123/avatar-320.png'); }); 25 Unit Tests: Component Internals
  • 27. — Example <Avatar /> component const Avatar = ({ className, path }) => {     const classes = classNames(‘avatar’, className);     return (         <img src={path} className={classes} />     ); } 27 Unit Tests:  Limit Your Implementation Knowledge
  • 28. — Example <UserProfile /> component class UserProfile extends React.Component {     _pathToAvatar(userId) {         return `my-cdn.com/users/${userId}/avatar-320.png`;     }     render() {         return (             <div className=“user”>                 <h3 className=“user__name”>{this.props.name}</h3>                 <Avatar                      className=“user__avatar”                      path=`${this._pathToAvatar(this.props.id)}`                  />            </div>         );     } } 28 Unit Tests:  Limit Your Implementation Knowledge
  • 29. — Bad Test it(‘rendered image points to correct asset’, () => {     const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);     const subject = userProfile.find(‘.icon’);     const result = subject.prop(’src');     expect(result).to.equal('my-cdn.com/users/123/avatar-320.png'); }); 29 Unit Tests:  Limit Your Implementation Knowledge
  • 30. — Bad Test it(‘rendered image points to correct asset’, () => {     const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);     const subject = userProfile.find(‘.icon’);     const result = subject.prop(’src');     expect(result).to.equal('my-cdn.com/users/123/avatar-320.png'); }); — Good Test it(‘rendered image points to correct asset’, () => {     const userProfile = shallow(<UserProfile name=“Taco” id=“123” />);     const subject = userProfile.find(Avatar);     const result = subject.prop(’path');     expect(result).to.equal('my-cdn.com/users/123/avatar-320.png'); }); 30 Unit Tests:  Limit Your Implementation Knowledge
  • 35. Problems with snapshot testing 35 Snapshot Tests 1. Validation of the “gold master” snapshot is manual and should be done by developer 2. Unlike unit tests, snapshot tests don’t provide specific guidance for what the original developer expected beyond the “actual behaviour” 3. They’re often fragile and generate lots of false negatives
  • 36. Best Practices 36 Snapshot Tests 1. Well-formatted snapshots 2. Proper diff logs 3. Skip composed components
  • 37. — Example import React from 'react'; import { shallow } from 'enzyme'; import { expect } from 'chai'; import generateSubtree from 'enzyme-to-json'; import Button from './button'; describe(‘<Button />’, () => {     it(‘Generated markup matches golden master’, function test() {         const subject = shallow(             <Button size=“small” color=“blue” icon=“save” text=“Save" />         );         const result = generateSubtree(subject);         expect(result).to.matchSnapshot( `${this.test.file}.snap`,  this.test.title);     }); }); 37 Snapshot Tests
  • 41. II. Do not test multiple “widgets” together
  • 45. Tips
  • 47. Bug Backlog Insights 47 Tips: Well-structured Bug Backlog 1. Identify missing tests 2. Improve code-review processes 3. Improve task spec 4. Training sessions 5. Pair programming
  • 49. Opportunities from Fixing Bugs 49 Tips: Opportunities from Fixing Bugs 1. Re-evaluate code readability 2. Investigate source of bug 3. Re-evaluate test readability 4. Re-evaluate existing test’s behaviour
  • 51. Thank You! You can reach me at: ✉ hi@mv.id.au @mehdivk