Desenvolvendo um Framework com TDD - Um Diário de Bordo - Agile Trends 2014

download Desenvolvendo um Framework com TDD - Um Diário de Bordo - Agile Trends 2014

If you can't read please download the document

Transcript of Desenvolvendo um Framework com TDD - Um Diário de Bordo - Agile Trends 2014

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());}