desenvolvendo um framework com tdd - um diário de bordo - agile trends 2014
TRANSCRIPT
Journey's Diary
Developing a framework using TDD
Eduardo Guerra
The Framework
Case Study
http://bit.do/tddframework
INTERFACEINTERFACE+ name conventions
+ anotations
+ entity class structure
Query Builder
Dynamic
Proxy
Framework
DSL
INTERFACE+ name conventions
+ anotations
+ entity class structure
QueryBuilder
Core
QueryBuilder JPA
QueryBuilder MongoDB
QueryBuilder JDBC
QueryBuilder Neo4J
For a good understander, the method name is enough!
public List
getPersonByNameOrAge
(String name, int age);
Using a simple naming pattern, you can define the entity and the properties to be used as filters.
That is the question!
To mock or
not to
mock?
What should I do when I have things that are hard to test, like external resources?
MOCK
Why?
It will make the test difficult
Test will be coupled with external APIs
It can make the test slow
But should I mock the external APIs themselves?
MOCK
Why not?
Create a class that encapsulates the access to this API!
It is a perfect match on the class needs
The API can be hard to mock
Decouple the class from the API
What should I do when I have classes that are not exposed to the class clients?
MOCK
Why not?
The solution can't be refactored without changing the test
Class don't need to be exposed
Test will be coupled to the solution
What should I do when my class have a hotspot or a dependence with variable behavior?
MOCK
What should I do when my class have a hotspot or a dependence with variable behavior?
Why?
Mock can explore all possibilities, such possible errors
Mock can be used to divide class responsibilities
Mock can be used to design the dependence API
QueryBuilder
MethodParser
Visitor that generates the query was mocked because it is a hotspot.
MOCK
MOCK
A composite to store query parameters was not mocked because it is an internal solution.
Unit or Integration ?
Can I use both on TDD?
Unit Test
decoupling
=
Creating unit tests you are
dividing responsibilities and defining the interaction among the
classes.
You are having feedback on your implementation, but it is not helping to define your design.
Integration Test
black box
=
If I'm defining my design using tests, when can I use integration tests?
Easy question! When your design is already defined!
Class AClass BClass C
Imagine that an architecture with these three classes
Class AClass C
MOCK
UNIT TEST
Developing Class A, the services needed from Class B were defined.
Class C interface were defined on its own TDD session.
UNIT TEST
Class AClass BClass C
INTEGRATION TEST
Now that everything is defined, you can use integration tests to develop Class B using TDD.
If you designed everything upfront, you don't need TDD as a design technique!
QueryExecutorQueryBuilderQueryVisitor
QueryBuilder
TESTED
TESTED
Since the other classes are already tested, QueryExecutor was developed using integration tests.
Big Refactorings
They will happen!
When you always search for the simplest solution, sometimes you reach a dead end!
However, most of the time these problems are concentrated on a single class and isolated from the others.
If that happens, STOP and refactor your solution!
QueryBuilder
method call
process
write query
method call
process
write query
store
refactorWhen appear a requirement where the processing depends on the next call...
Final Considerations
What is
missing?
You still have to know
patterns to understand the solution that you are driving through
the tests.
Sophisticated solutions sometimes are the better ones for the problem.
Don't avoid them!
You can use TDD only for development, or also as a design technique.
If you choose design you can not avoid mocking!
@Testpublic void presentationEnd(){ Presentation p = new Presentation(); Audience a = new Audience(); p.setAudience(a); p.perform(); p.end(); p.thanksEveryone(); assertTrue(a.isApplauding());}