test-driven development - vilniaus universitetasragaisis/psi_mag2015/lecture_tdd.pdf · test-driven...

58
Test-driven development And how we do it at WIX Mantas Indrašius Software Engineer WIX.COM

Upload: others

Post on 10-Jun-2020

14 views

Category:

Documents


0 download

TRANSCRIPT

Test-driven developmentAnd how we do it at WIX

Mantas IndrašiusSoftware EngineerWIX.COM

Agenda

● Tests overview● Test-driven development (TDD)● The Bowling Game demo● Kickstarting a project using TDD● How we do it in WIX

Tests overview

Why writing tests

● Reliability● Freedom of change● Instant/fast feedback● Tests as specification● Design hints for free● Saves cost

● Code is changing all the time● Most projects are developed in teams● Humans do mistakes● How do we know if changing A does not

break B?● Are we stable enough to deploy?● Do we trust the developers?

Reliability

Developer feedback

Freedom of change

● Well written code is reusable● Change in single line of code might break

unintended parts of the system● Changing code of someone else is a risk to

introduce bugs● Can we refactor and be sure no bugs were

introduced?

Feedback from process

Feedback cycles

● Unit tests - a second or two● Acceptance test - 1-10 minutes● Manual testing / using debugger - 1-30 minutes● Continuous integration - 10-60 minutes● Peer review - few hours● QA - from few hours to days● Production - days, weeks or months● And we do it in multiple iterations

The Word of Wisdom

Fail as fast as you can!

Tests as specification

● Specifications are hard to create and maintain● Specifications contain errors and inconsistencies● Most of inconsistencies are discovered in the coding

phase● Amendments are late and costly● Most of requirements could be described as

acceptance tests in a readable manner

Design hints for free

● It’s a rule: good design = testable code● Hard to write tests hint the code under test

has design flaws● Tests can guide how the bad design could

be improved● Does it make sense to write the test after

the code?

Saves cost

● We spend a lot of time on debugger● Better design requires less maintenance● Frequent deployments = smaller impact● Less bugs = lower fixing cost, happy users● And...

Saves cost

● We spend a lot of time on debugger● Better design requires less maintenance● Frequent deployments = smaller impact● Less bugs = lower fixing cost, happy users● We can fire the analysts, testers and

release manager :)

Saves cost

● We spend a lot of time on debugger● Better design requires less maintenance● Frequent deployments = smaller impact● Less bugs = lower fixing cost, happy users● We can fire the analysts, testers and

release manager :)● They can help improving the product even

more

Unit tests

● We test object behavior● We set preconditions and expectations● Test behavior with different input

arguments● We use object mocks to isolate the class

under test

Unit tests

Unit tests

TDD(Test-driven development)

What is TDD?

● It’s a development process of very short development cycles based on a rapid feedback

● It’s a design activity● It’s a design support tool● It’s a safety net of regression coverage

The basics of TDD process

● Write a test● Run all tests and see the new one fails● Write minimal amount of code for the test

to pass● Run all the tests and see them pass● Refactor code to acceptable standards

The Golden Rule of TDD

Never write a new functionality without a failing test

Red - Green - Refactor

Levels of testing

● Acceptance - does the whole system work?● Integration - does our code work with 3rd

party?● Unit - do our objects do the right thing?

Pyramid of developer tests

The Bigger Picture

● Write a failing acceptance test and keep it so

● Go to the class level and do TDD with unit and/or integration tests

● Once finished, check the acceptance test● If it’s still not passing, continue with

changes in the class level

The Bigger Picture

Acceptance testing

Why acceptance tests are not enough

● Acceptance tests are slow● They are not suitable to test edge cases● They don’t help maintaining a good design● They are not allowed to have access to the

internal components of the system

Testing a system component

● In big systems working with acceptance tests requires great effort

● So we split the system into components and test them End-to-End (E2E)

● We keep the minimum of acceptance tests to prove the system is working

● We burden E2E with more thorough use cases

End-to-End testing (E2E)

● We isolate the component in a black-box● We are not allowed to interact with the

internals of the component● If it’s a server, we test it from the protocol

client perspective● If it’s UI, we mimic the user mouse and

keyboard inputs

End-to-End testing (E2E)

End-to-End testing (E2E)

End-to-End testing (E2E)

How TDD helps us?

● We learn to grow software incrementally● We write just enough code for a feature● We are guided to maintain a sustainable design● At any given time we have a ready to deploy

system● At any given time we have the most up-to-date

specification of how system works

Agile loves TDD

● Incremental development● Short feedback loop● Working software over documentation● There is no component someone owns● Quality first

Let’s see it in actionDemo

Kickstarting a projectUsing TDD

The first step: The Walking Skeleton

● The Goal: Build the infrastructure● Choose the minimal system feature to focus

on infrastructure● Infrastructure should include all the

essential anticipated components● We should learn how to build and deploy● Pass the first acceptance test

The Walking Skeleton on legacy

● The Goal: Build the infrastructure● Choose the simplest existing system feature

and focus on building the infrastructure● Infrastructure should include all the

essential anticipated components● Pass the first acceptance test● Cover the other cases one-by-one

The context of the first step

Uncertainty in test-first and test-later

Working with 3rd party

● It’s the code we don’t control and we cannot change

● In unit tests don’t mock types from 3rd party

● Write a thin adapter layer and use it in your mocks

● Run an integration test on this layer

Testing the 3rd party adapter layer

How we do it in WIX

What do we do in WIX

● Website editing and publishing platform● User account / business management

system● App Market● Hundreds of small applications in the

market● Business verticals: hotels, reservations,

music, photography etc

Scale of WIX

● More than 57,000,000 users● 1.2PB of data (1.5TB per day)● 900 servers in 3 data centers● 3 clouds (Google, Amazon, Azure)● 50000 dynamic requests per minute● More than 900 employees

Engineering in WIX

● WIX is a company with developer-centric approach

● Excellence of Engineering is our priority to adding new features

● Every developer in WIX is also a DevOp● Service oriented architecture● We do continuous delivery

TDD at WIX

● We believe in TDD, we start learning it from the first day at work

● Client-side and server-side do it separately in their isolated ecosystems

● We approach TDD from E2E rather than acceptance testing

● TDD empowers us to practice the Continuous delivery approach

Continuous delivery

Our Concerns

● Continuous integration● Backwards and forwards compatibility● Feature oriented design● Experiments● Data inconsistency

Tools

● TeamCity - continuous integration and release

● LifeCycle - a custom built tool to manage the project lifecycles (version management, delivery)

● Artifactory - storage for artifacts● Chef - deployments / server provisioning

Client-side infrastructure

● AngularJS for building the rich UI● Grunt for running the build (incl. tests)● Jasmine for describing test behavior● PhantomJS for testing units● Selenium with Protractor for E2E or

acceptance tests● SauceLabs for cross-platform testing

Client-side build

● Start PhantomJS and run the unit tests● Start a fake API server on NodeJS● Start the controlled browsers● Run the E2E test suite against them● Clean up & deliver the artifact

Server-side infrastructure

● Scala/Java for server applications● Maven as a build tool● specs2/JUnit for describing the test

behavior● JMock/Mockito for testing units● Custom HTTP test-kit for HTML/JSON

matching

Server-side build

● Run unit tests● Setup the embedded environment (MySQL,

MongoDB, Cassandra)● Start the fake 3rd party services● Start the server under test● Run the E2E test suite against it● Clean up & deliver the artifact

Release process in WIX

Ačiū!Any Questions?