My talk at the Swinburne University on 09/10/2019. Presented to students as part of the series, Development Projects - Tools and Practices.
Level: Beginner
2. You will learn
• Software testing - overview
• TDD vs Writing unit tests
• TDD in action - Demo
• Few techniques, tools and tips
• Time for question / discussions
(feel free to interrupt any time)
9. Unit Tests
• Unit of code,
e.g., a function
• Smallest testable piece
• Assertions
• Data
• Quick to run (short feedback loop)
• Isolation (No connection to external state)
13. Add test /
refactor
Fix
Run test
Fail
• Start with a failing test
• Make test pass
• Write more tests
• Make test pass … cont.
• Refactoring is part of the process
• Red-green-refactor
Pass
14. First test round - always FAIL !
( if passed then we have a bigger problem to deal with :D )
Minimal code required to PASS the tests.
No speculative code.
15. TDD vs Writing testsTest Driven Development
A software development process
Upfront design thinking
Tests come first
More about software design than
testing
Writing unit tests
A way to ensure code works
An after thought to confirm
assertions
Tests come second
More about testing than software
design
Knowing how to write better unit tests is crucial to TDD
Vs
16. Feedback loop is minutes.
Source http://www.agilemodeling.com/essays/costOfChange.htm
17. TDD Benefits
Better designed code
• The interactions are already understood
Clear business requirements
• Tests act as a well-defined specification
Improved code quality
• Minimum code required to make the test pass
Focus
• Narrow focus. High productivity.
Confidence to refactor
• Touching the code after few weeks, new team members etc.
Evolutionary technique
• Small steps towards end goal. Few lines of code at a time.
Detect errors early in the process
• Assertions are already there
19. Demo
• NodeJS – development platform
• https://nodejs.org/en/download/
• Jest – Test tool
• https://jestjs.io/
A function to check strong passwords ...
%mkdir password && cd $_
%git init
%npm init --yes
%npm i jest
%mkdir test
%touch test/password.test.js
f()input output
assertions
test("description", function);
e.g.,
test("test description", () => {
expect(1+2).toBe(3);
});
20. What happened ?
• We did NOT start with the implementation
• We postponed answering the question “HOW?”
• We focused on expectations
• We clarified the requirements / specification
• We understood the inputs and outputs
• We started with the simplest form of the function, i.e., smallest step
• We observed failing tests
• We did small increments until the function is satisfactory
• We detect bugs early in the implementation
21. We ended up with
A good test coverage Minimal amount of code
Code satisfies current
business expectations /
assertions
Assertions are captured
as a test specification
22. TDD – Criticisms and Practicality
• TDD Zealots – do this or you are wrong
• Reactance theory – freedom – teams - benefits
• Sometimes the first test doesn’t come naturally
• Playing with code and other components first
• Tests are good as long as all relevant assertions are covered.
• ATDD - Acceptance test–driven development
• Bad unit tests -> bad TDD
• Fast test execution
• TDD - needs practice
• Measure test coverage
23. Tools that can help us
Test tools Development language
JSUnit, Jasmine, Tape, Jest, Mocha, Chai, Sinon Node / Javascript
Junit, Mockito, TestNG Java
PyUnit, Nose, pytest Python
Go test Go
Rspec, Test::Unit (builtin) Ruby
PHPUnit PHP
Cppunit, Google test, Boost C++
* These tools are OPTIONAL. But can make it easier to write and execute tests
25. Dependencies
• HTTP calls, Database, File IO
• Inconsistent outcome of the test
• Network connectivity issues
• External state changes
• Time consuming, Error-prone
• CI/CD pipelines
• Stunt Test Doubles
• Cheaper than the real one ;-)
• E.g., Sinon :- Spy/Stub/Mock
26. Spy Stub Mock
Gather information about a
function call (spying).
A spy does not replace the
existing function.
e.g., to check if a function is
called
Replaces the existing function.
e.g., to remove external dependencies.
Replaces the whole object.
e.g., Handy to test more than one
function.
var callback = sinon.spy();
myFunction(true, callback);
sinon.assert(callback.calledOnce);
var post = sinon.stub($, 'post’);
post.yields();
myFunction(user, function(){} );
post.restore();
sinon.assert.calledWith(post, expectedUrl,
expectedParams);
var storeMock = sinon.mock(store);
storeMock.expects('get').withArgs('data').retu
rns(0);
storeMock.expects('set').once().withArgs('data
', 1);
myFunction();
storeMock.restore();
storeMock.verify();
28. Microservices
• Is an architecture style
• Loosely coupled services
• A service represents a specific business function
• Invoice service
• Customer service
• Payment service
• Separately deployed in different runtimes
• Highly maintainable, scalable and testable
29. runtime
TDD with Microservices
• Different runtimes and tech stacks
• Service – service interactions
• Mocks
• Version control
Runtime
Customer
Object
Invoice
Object
runtime
Customer
Service
Invoice
Service
30. TDD with Microservices
• Integration tests can be used to test the validity of service-service
interactions
• But TDD needs unit tests (short feedback loop)
31. Pacts
• Service contracts
• Pact framework
• A contract testing tool
• Consumer-driven
• Pact tests are unit tests
• TDD
Pact broker
Pact file
( version controlled )
Customer
Service
Invoice
Service
Unit
tests
Consumer
Provider
34. TDD for frontend
• Traditional frontend development
• Modern frameworks, come with all the goodies to start TDD
• e.g., react, angular,
• TDD for services and models
• E.g,, Enzyme -> a JavaScript Testing utility for React
36. Behaviour-Driven Development
• Flavor that can be used to write unit tests
• Provide a structure
• Given, when, then format , e.g.,
Given('The user is authorised', function() {});
When('The user requests invoice data', function() {});
Then(‘Correct invoices are returned', function() {});
• Human readable - Technical and non-technical users
• TDD and BDD complements each other
• Many tools, e.g., Cucumber, JBehave, RSpec.
37. Summary
• TDD is a software development methodology
• Start with failing tests, refactor until test pass.
Continue…
• Business requirements are captured as tests
• Many benefits
• Many tools
• Challenges in architectures like microservices
• To TDD or not to TDD? Case by case.
38. Further reading
• Test-Driven Development by Example – Kent Beck
• http://agiledata.org/essays/tdd.html
• https://www.agilealliance.org