This presentation is simply for motivating developers towards test automation and test-driven development. It discusses lightly unit testing, mocking and integration testing, too.
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Test driven development
1. Test-Driven Development
(TDD)
Sharafat Ibn Mollah Mosharraf
Software Engineer,
Therap (BD) Ltd.
sharafat@therapservices.net
2. Overview
● The need for test automation
● Writing test-first code
● Unit Test Frameworks
● Mocking Frameworks
● Integration Testing
● Continuous Integration Tools
Test-Driven Development (TDD) 2 / 29
3. The Need for Test Automation
Test-Driven Development (TDD) 3 / 29
4. Traditional Programming Practice - 1
● We code, build, deploy to app server and manually test
whether our code works.
● We repeat the same process until we're affirmed that our
code works.
● If code building takes 1 minute,
server restarting takes 2 minutes,
logging in and browsing to the desired page to test the code
takes 1 minute,
then one round of testing takes a total of 4 minutes.
● If 10 rounds are needed to finally make the code work, total
time wasted is 40 minutes.
● If testing could be automated by bypassing these lengthy
processes, then this 40 minutes could be saved.
Test-Driven Development (TDD) 4 / 29
5. Traditional Programming Practice - 2
returns ACTIVE,
uses
1 List of all users of an application LOCKED,
DISABLED users
List of LOCKED users to reset uses but gets ALL users returned
2
their password instead of only LOCKED users
Naive coder changes
3
to return only LOCKED users.
consequence
(2) works awesome, but now (1) doesn't work as expected.
However, the naive coder didn't even know feature (1) exists, so, the new bug in (1) gets
overlooked until customer complaints.
lesson learned
Don't trust coders!! Whenever a new feature is implemented, test the whole system again.
R u crazy?? There are hundreds
solution
of features in the app!!! Automate the testing process :)
6. Okay, understood. After writing code, we need
to write test codes, too.
WRONG!!!
We need to write test code before writing actual code.
Why on earth is that???
Test-Driven Development (TDD) 6 / 29
7. Writing Test Code After Writing
Actual Code is Difficult
Before we learn why, let's take a look at how a
test code can be written
Test-Driven Development (TDD) 7 / 29
8. Writing Naive Test Code
Actual code: Test code:
Test-Driven Development (TDD) 8 / 29
9. Writing Test Code After Actual Code
Becomes Difficult - An Example
Actual (pseudo)code: The test code should do
something like the following:
1. Add a few users including
ACTIVE, LOCKED &
DISABLED to database.
2. Call the actual code where the
user list is retrieved.
3. Check whether all the users
added above have been
returned.
But we can't single-out the actual
code where user list is retrieved;
that task is buried under the
listUsers() method which returns
nothing!
Test-Driven Development (TDD) 9 / 29
10. Writing Testable Code
1. Write the test code first:
Test-Driven Development (TDD) 10 / 29
11. Writing Testable Code...
2. Make sure your test code fails when run.
Huh! I haven't implemented the code yet!
The test code will obviously fail!!
Wrong again!! :P
Quite interestingly, your test code might pass before you've written
your actual code, which indicates your test code itself is incorrectly
written and needs to be tested... :P
Test-Driven Development (TDD) 11 / 29
12. Writing Testable Code...
3. Now write the actual code in the way expected by the test code:
4. Run the test.
If the test passes, move on to the next step (step 5).
If the test fails, find out the bug in your actual code and fix it. Run the test
again until it passes.
5. Write some more test code if you have other codes which can be tested.
Repeat steps 1 to 4 for those code.
6. Finish off the rest of the code: (see next slide)
Test-Driven Development (TDD) 12 / 29
14. Added Bonus of TDD
● Code conforms to good software design
principles:
■ Low coupling
■ High cohesion
● Test code becomes the documentation and
usage example of the written application/API
■ However, you need to make sure you write the
test code well, following good practices,
standards and patterns.
Test-Driven Development (TDD) 14 / 29
15. Unit Testing Frameworks
● The previous -based test code is not
very appealing as the test program fails
■ at the first assertion failure line, skipping the
evaluation of the rest of the assertions
■ with simply an "assertion failed" message without
any clue about what the actual value of
something was
● We want to
■ check all assertions and figure out which specific
ones fails
■ compare the actual value to the expected one
Test-Driven Development (TDD) 15 / 29
16. Unit Testing Frameworks...
● Several frameworks have been developed
for the aforementioned purposes:
■ xUnit (JUnit, PHPUnit, NUnit, DBUnit etc.)
■ TestNG
● And a lot more...
● The above test code written in JUnit would
look like the following:
Test-Driven Development (TDD) 16 / 29
18. Mocking
● Unit testing is for testing an independent
unit of code.
● Unit testing assumes the code to be tested is
independent of any other code.
● However, in the previous example, the code
to be tested ( ) is dependent
on database.
● To remove the dependency, the actual
object (database in our example) is replaced
with a fake object, known as a mock object.
Test-Driven Development (TDD) 18 / 29
19. Naive Approach for Mocking
Actual Code:
Test-Driven Development (TDD) 19 / 29
20. Naive Approach for Mocking...
Mock Connection Implementation:
Test-Driven Development (TDD) 20 / 29
21. Naive Approach for Mocking...
Test Code:
Test-Driven Development (TDD) 21 / 29
22. Mocking Frameworks
● To ease the tedious task of creating mock
objects, several mocking frameworks have
been developed, the most populars among
which are (Java-only mentioned here):
■ EasyMock, PowerMock
■ Mockito
● Using Mockito would save you from writing
the MockConnection class above and make
the aforementioned test code look like the
following: (see next slide)
Test-Driven Development (TDD) 22 / 29
24. Unit Testing is Not Enough for Test
Automation
● If the previous test for passes,
does that guarantee your application works?
No.
● The independence nature of code unit is the
culprit.
● The previous test passes with a mock
connection. But when real database will be
used, there is a chance of things not going well
altogether.
(Can you come up with a few ideas why?)
Test-Driven Development (TDD) 24 / 29
25. Unit vs Integration Testing - Analogy
● When small units are tested independent of one another, it's called
unit testing.
● When the interaction among components are tested, it's called
integration testing.
● Suppose you're building a car and you've unit tested and confirmed
that your tires work as expected, engine works as expected,
speedometer works as expected - all parts independent of one
another.
Now, when you build a car whose wheels are 215/65/15*, but you fit
205/55/15 tires to it, if you run an integration test, you'll find out that
driving the car at 55 MPH causes the speedometer to read 60 MPH
(as the actual tire circumference is 8.2% shorter than the expected
one), which is an error.
Integration tests are used to identify such error.
* 215/65/15 is nominal width of tire (in mm) / ratio of height to width (aspect ratio) / rim diameter code
Test-Driven Development (TDD) 25 / 29
26. Continuous Integration Tools
● There is no syntactic difference between unit and integration
testing; the difference is rather semantic.
● As the environment setup for integration test is complex and
running the tests take much time, integration testing is
usually performed in a dedicated server.
● Developers commit their code to the server and before the
commits get merged, all the integration tests are run to make
sure the commits don't cause other parts of the application to
break.
● Developers get notified by the CI server automatically of the
result of the tests.
● Some most popular CI tools include (only Java-specifics are
mentioned here):
■ CruiseControl
■ Hudson
Test-Driven Development (TDD) 26 / 29
27. Principles of Continuous Integration
● Maintain a Code Repository
● Automate the build
● Make the build self-testing
● Everyone commits to the baseline
● Every commit (to baseline) should be built
● Keep the build fast
● Test in a clone of production environment
● Make it easy to get the latest deliverables
● Everyone can see the results of the latest
builds
● Automate deployment
Test-Driven Development (TDD) 27 / 29
28. Further Reading
Test Driven Development: By Example
Kent Beck
Addison-Wesley (2002)
xUnit Test Patterns: Refactoring Test Code
Gerard Meszaros
Addison-Wesley (2007)
Clean Code: A Handbook of Agile Software Craftsmanship
Robert C. Martin
Prentice Hall (2008)
Test-Driven Development (TDD) 28 / 29
29. Further Reading...
Continuous Integration: Improving Software Quality and
Reducing Risk
Paul M. Duvall
Addison-Wesley (2007)
Continuous Delivery: Reliable Software Releases through Build,
Test, and Deployment Automation (Addison-Wesley Signature Series
(Fowler))
Jez Humble
Addison-Wesley (2010)
Unit tests lie: that's why I love them (Blog Article [2011])
Arialdo Martini
This article explains quite well why unit testing is not sufficient and integration
testing is needed.
Test-Driven Development (TDD) 29 / 29