Test-driven development And how we do it at WIX Mantas Indrašius Software Engineer WIX.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
Reliability 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?
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 action Demo
Kickstarting a project Using 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 testlater
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?