Post on 07-May-2015
description
Test-Driven Development&
Continuous Integration
Hao-Cheng Lee
本著作係依據創用 CC Attribution-ShareAlike 3.0 Unported 授權條款進行授權。如欲瀏覽本授權條款之副本,請造訪
http://creativecommons.org/licenses/by-sa/3.0/ ,或寄信至 Creative Commons, 171 Second Street, Suite 300, San
Francisco, California, 94105, USA 。
About me
● Hao-Cheng Lee● Java Engineer for 7+ years● Quality Engineer@Yahoo (till yesterday ;-))● Interested in Java, Scala, TDD, CI● email: haocheng.lee@gmail.com● twitter: https://twitter.com/#!/haocheng
Agenda
● What is TDD?
● Why use TDD?
● How to do TDD?
● What is CI?
● Why use CI?
● TDD + CI
TDD =
TFD +
Refactoring
Not about writing tests...
TDD is about writing better
code
from http://ch.englishbaby.com/forum/LifeTalk/thread/441379
Test Myths
I have no time for testing
My code is BUG-FREE!
QA will do the testing
Black Box Testing
from http://www.jasonser.com/marketing-black-box/
Faster
from http://cllctr.com/view/c2fdb4d2625e109069c843ea1bb99e50
from Test Driven Development Tutorial by Kirrily Robert
Faster
● Shorter release cycle
● Automation saves time
● Find bugs earlier
Better
from http://www.nataliedee.com/archives/2005/sep/
Better
● Greater code coverage
● The courage to refactor
● Prevent regression bugs
● Improve your design
"I'm not a great programmer; I'm just a good programmer with great habits." - Kent Beck
Testing the Old Way
TDD
TDD
How to do TDD?
● Design: figure out what you want to do● Test: write a test to express the design
○ It should FAIL● Implement: write the code● Test again
○ It should PASS
Design
We need a method add(), which takes two parameters and add
them together, then it will return the result.
Test
java.lang.AssertionError: expected:<2> but was:<0>...at tw.idv.haocheng.play.CalculatorTest.one_plus_one_is_two(CalculatorTest.java:20)
FAIL
Implement
PASS
Write the least code to make the test pass
More Test
java.lang.AssertionError: expected:<4> but was:<2>...at tw.idv.haocheng.play.CalculatorTest.two_plus_two_is_four(CalculatorTest.java:25)
FAIL
Implement
PASS
Design
The add() method only accept positive numbers
Test
java.lang.AssertionError: IllegalArgumentException expectedat org.junit.Assert.fail(Assert.java:91)at tw.idv.haocheng.play.CalculatorTest.negative_numbers_will_throw_exception(CalculatorTest.java:32)
FAIL
Implement
PASS
Unit Test Frameworks
● Java - JUni● Python - PyUnit● PHP - PHPUnit● Ruby - Test:Unit● Javascript - Jasmine● .Net - NUnit
Good Test
● One test per scenario● Test in isolation● Readability● Minimum Test Fixture● Repeatable
Bad Smell
● NO Assert/Meaningless Assert● High maintenance cost● Interacting Tests● Require manual debugging ● Evil Singleton
When is enough enough?
● One Test per class● Testing the feature● Find bugs, add tests● Skip Getter/Setter if generated● Skip Private methods● Code coverage
There's No Silver Bullet
from http://www.penn-olson.com/2009/12/22/social-media-the-silver-bullet/
It takes time...
from http://chunkeat626.blogspot.com/2010_11_01_archive.html
Need to maintain tests
from http://www.flickr.com/photos/ilike/2443295369/
TDD is not suitable for...
Continuous Integration
Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily – leading to multiple integrations per day. -- Martin Fowler
Why CI?
●Rapid Feedback
●Reduced Risk
●Collective Ownership
●Continuous Deployment
●Offload from people
Why TDD + CI?
Effective tests must be automated
from http://www.laurentbrouat.com/why-you-should-stop-sending-auto-dms/automated/
Write once, run often
●Write tests once●Run frequently●No human input●Common output
Best Practices of CI
●Single Source Repository
●Commit often
●Make Your Build Self-Testing
●Automate the Build
●Build fast
Extensible continuous integration server
What is Jenkins?
●Open-source CI server
●Easy to install and use
●Extensibility
Why Jenkins?
●GUI to manage
●Strong community and eco-system
●Distributed builds
●Open Source and Free!
mailing list subscription is increasing
GitHub members is also increasing
Basic Features
●Notice a change
●Check out source code
●Execute builds/tests
●Record and publish results
●Notify developers
CI Overview
from Continuous integration with Hudson
Notice a change
●Build Periodically
●Depend on other projects
●Poll SCM○Subversion Push vs. Pull
Check out source code
●Subversion
●CVS
●Git
●Mercurial
●Perforce
Execute builds/tests
●Java○ Ant, Maven, Gradle
●.Net○ MSBuild, PowerShell
●Shell Script○ Python, Ruby, Groovy
Record and publish results
●JUnit●TestNG●Findbugs●Cobertura●Checkstyle●PMD
Job Status
Job State: Job Stability:
Findbugs Integration
Cobertura Integration
Project Relationship
Notify developers
● Twitter● email● RSS● IM● IDE● Android/iPhone● Firefox
Jenkins on Eclipse
Update Site: http://code.google.com/p/hudson-eclipse/
Jenkins on Android
● Android Market● Jenkins Wiki
eXtreme Feedback Panel plugin
Jenkins Sound pluginhttp://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Sounds+plugin
Installation&Upgrade
● Download Tomcat 7
● Download latest jenkins.war
● Put jenkins.war under webapps
● Start Tomcat
Create a Job
Configure a Job
Configure Jenkins
Manage Plugins
Jenkins for non-Java Projects
● Python
● PHP
● Ruby
● .Net
Reading List
● The Bowling Game Kata● Unit Testing Guidelines● Why are we embarrassed to admit that we don’t know how
to write tests? (中譯版本)● "The Clean Code Talks -- Unit Testing"● Top 10 things which make your code hard to test
References - Test-Driven Development
● Test Driven Development Tutorial by Kirrily Robert● Engineer Notebook: An Extreme Programming Episode by
Robert C. Martin and Robert S. Koss● Technical Debt by Martin Fowler● InfoQ: Testing Misconceptions by Liam O'Connor● Unit Test Isolation● Erratic Test● Singletons are Evil ● RSpec 讓你愛上寫測試
References - Continuous Integration
● Jenkins: http://jenkins-ci.org/● Mailing List: http://groups.google.com/group/jenkinsci-
users ● Wiki: http://wiki.jenkins-ci.org/ ● Follow @jenkinsci on Twitter● Continous Integration by Martin Fowler● Continuous Integration with Hudson - the book● Continuous Integration with Hudson on JavaWorld