Pages

Showing posts with label TDD. Show all posts
Showing posts with label TDD. Show all posts

Tuesday, February 11, 2020

Design Decisions

I was practising a Kata I haven't done in a while because I wanted to add a recording to the new Page I created dedicated to TDD Katas. The Kata in question was the Roman Numerals Kata (From Roman to Arabic).

After doing the Kata I ended up with this implementation:



This is fine, the solution worked but I just didn't like that those two nested loops seemed a bit of a lot of complexity. Probably not the best solution from the point of view of performance. I wanted to try something else. So I deleted that code and without deleting the tests I wrote this:



To me this seemed a bit better and probably faster. Optimisations are something that we should always postpone. Remember the saying?

Make it run, then make it nice, then make it fast.

Early optimisations can lead to unwanted over-engineering and some other problems. TDD teaches us that we need to grow our code gradually. But then how can we just refactor to something completely different than what we just got?

Once we have written all our tests and we are happy with our refactoring, the tests will act as our documentation, so even if we were to delete all the code and just leave the tests, we could recreate the code. So that is what I did initially to create that second implementation.

After observing the new implementation and compare it to the previous one, I decided to TDD to see if I could get to the code in the second implementation. I discovered that at the point where I was doing the refactoring after making the test for number 6 pass, here was the place where I could make a design decision and choose not to extract an enum and instead try something else.

This time the Kata has once more proven that TDD is not just capable of making safer code but also drive the design even when we are looking for a faster solution than the one we have.


Here the video for that Kata:
 

Saturday, February 8, 2020

TDD Katas

I am planning to re-organise some of the content of the blog. From now own TDD Katas will no longer be posted as blog posts, instead they will be added to the page "TDD Katas" on this blog under the following url: http://javing.blogspot.com/p/tdd_9.html

Friday, August 17, 2018

Refactoring - How do I start?



According with the Software-craftsmanship legend Sandro Mancuso we should start:

  • Refactoring from the deepest nested branch of the code and work our way inside out.
  • Test from the shortest/less nested branch of the code and work our way from outside in.

Monday, April 10, 2017

Mocking static method calls

Very simple example on how we can use method delegation to enable unit testing where there is a dependency to an static method call.



Tuesday, March 28, 2017

13 minutes TDD warm up

O wow! I haven't realised for how long I didn't write a blog post.  I better start posting again, but first... Let's warm up with a bit of TDD. Ok I've got 13 minutes, lets put on some music and see if I can do a Kata.

Note: To view in high resolution, open the full screen view and change the video quality using the wheel.

                                           
    The video is raw unedited, the music is coming from youtube in my second screen.13 roman digits, parsed in 13 minutes ;)


Wednesday, March 11, 2015

Yet Another Blog Article About Acceptance Testing


Acceptance tests are tests conducted to determine if the requirements of a specification are met.
In modern software development, we call this specification, acceptance criteria.

“Whenever possible” it would be desirable to acceptance test, the system end to end.
By end to end, I mean talking to the system from the outside, through its interfaces.

Note that at the beginning of the previous paragraph, I said “Whenever possible”.
The reason for this, is that it would be risky and also costly to integration test our code(against other code, we don't control/own). Sometime applications within a system, don't even belong to our company or they are too costly and slow to run. Because of this, the amount of system full stack tests/functional tests, should be very reduced/almost none.

In acceptance testing we often start from an assumption about those external systems we cannot control. The parts out of our control are faked and the acceptance criteria, is aimed to those parts we control.

When writing an acceptance test, there is a commonly used format to define the acceptance criteria. It is well known as the “given,when,then” format:

- given: The setup/preconditions, of the scenario that we will test. Its contains what is that we expect from those remote systems(either internal or external) on which we depend.
- when: Is the specific call to the exposed interface we are testing.
- then: Is the validation of the results.

Today's acceptance test are written with the help of live specification frameworks, such as: Jbehave, Fit, Fitnesse, Concordion, Yatspec...
The use out this tools, will make easier to both understand complex scenarios and maintain criteria.


Understanding Yatspec

Next I will talk about writing acceptance tests with a popular live specification framework called Yatspec. I will explain some of its features and describe the way it presents the test report. Also I will explain with an example how we could stub systems out of our control and use them in our acceptance test.

About yatspec
-
its a Live specification framework for Java(https://code.google.com/p/yatspec/)
-produces readable Html
-supports table/parametrized tests
-allows writing in given-when-then style

 
The scenario
The application we will be testing, will receive a GET request from a client, then it will send subsequent GET requests to two remote systems(A and B), process the responses and POST the result to a third system(C), just before returning it to the client.



The criteria
-Given System A will reply 1 2 3
-And System B will reply 4 5 6
-When the client asks for the known odd numbers
-Then the application responds 1 3 5
-Then 'System C' receives 1 3 5


Creating html reports
Before going in depth into our example, I want to expend some time discussing how Yatspec reports look like, and what are the basics in order to create them(If you want to go directly to the scenario implementation, just skip this section).

When a Yatspec specifications are run, it will generate a html report. Advance options, can allow you to publish it remotely, but by default it will be written to a temporary file in the file system.
The terminal will tell you where it is like this:
Yatspec output:
/tmp/acceptancetests/KnownOddNumbersTest.html
We can navigate to it from the browsers url:
file:///tmp/acceptancetests/KnownOddNumbersTest.html

Lets have a look at how it is structured:


(a) Is the title of the report. If Yatspec finds the postfix 'Test' on the class name, it will remove it and just present the rest of the title.

 @RunWith(SpecRunner.class)  
 public class KnownOddNumbersTest extends TestState {  
      //Your tests  
 ...  
 }  


(b) In the contents section you will see a summary of all the test names(There can be multiple tests) in the same specification.



(c)This is the test name. We don't need to add any additional, anotations, all we need is to write our test names in “camel case”. If the test throws any exception, it will not be shown in the report.


 @Test  
 public void shouldReceiveResultWhenARequestIsSentToTheApplication() throws Exception {  
       //Test body...  
 }  


(d) At the beginning of each test, the criteria will be presented. Yatspec will use the contents of the method body to generate it. The methods given(), and(), when(), then() are inherited from TestState.java(latter I will explain how to use them).

 
 @Test  
   public void shouldReceiveResultWhenARequestIsSentToTheApplication() throws Exception {  
     given(systemARepliesWithNumbers("1,2,3"));  
     and(systemBRepliesWithNumbers("4,5,6"));  
     when(aRequestIsSentToTheApplication());  
     then(theApplicationReturnedValue(), is("1,3,5"));  
     then(systemCReceivedValue(),is("1,3,5"));  
   }  

(e) This is where test result will be shown. Yatspec will colour this part in green if the test passes , in red if the test fail or in orange it the test is not run.

(f)Interesting givens are the preconditions for the test to run. This preconditions are stored in the class TestState.java in an object called interestingGivens. The way we would commonly do this by passing a GivensBuilder object to the the method given(). Also the method and() can be used to add more information in our interesting givens.
 
 @Test  
   public void shouldReceiveResultWhenARequestIsSentToTheApplication() throws Exception {  
     given(systemARepliesWithNumbers("1,2,3"));  
     and(systemBRepliesWithNumbers("4,5,6"));  
     //...  
   }  
   private GivensBuilder systemARepliesWithNumbers(String numbers) {  
     return givens -> {  
       givens.add("system A returns", numbers);  
       return givens;  
     };  
   }  
   private GivensBuilder systemBRepliesWithNumbers(String numbers) {  
     return givens -> {  
       givens.add("system B returns", numbers);  
       return givens;  
     };  
   }  

(g) This are the captured inputs and outputs. Its purpose is to record values that go in or out of any component in the workflow. TestState.java contains an object called capturedInputsAndOutputs to which we can add or query from. Comonly we would indirectly add a value to the capturedInputsAndOutputs to track the response of our application so it can be verified latter, via a parameter of type ActionUnderTest.java to the when() clause method.

 @Test  
   public void shouldReceiveResultWhenARequestIsSentToTheApplication() throws Exception {  
     //...  
     when(aRequestIsSentToTheApplication());  
     //...  
   }  
 private ActionUnderTest aRequestIsSentToTheApplication() {  
     return (givens, captured) -> {   
 //The second object of this lambda is capturedInputsAndOutputs  
       captures.add("application response", newClient()  
           .target("http://localhost:9999/")  
           .request().get().readEntity(String.class));  
       return captures;  
     };  
   }  


(h) This are the final verifications. They are created by the then() method. You will distinguish if the output was generated by the then() method, because it is not highlighted in yellow.
An StateExtractor.java is responsible for the values in this section. The state extractor will take from the captures the values that where recorded previously so a matcher can verify if they are correct.


 @Test  
   public void shouldReceiveResultWhenARequestIsSentToTheApplication() throws Exception {  
     //...  
     then(theApplicationReturnedValue(), is("1,3,5"));  
   }  
 private StateExtractor<String> theApplicationReturnedValue() {  
     return captures -> captures.getType("application response", String.class);  
   }  
 }  

The scenario implementation
Now that we understand the criteria and we have some basic understanding of Yatspec reports. Lets write an acceptance test for the criteria described before.

In our scenario System A, B and C are out of our control(Lets imagine they are owned by companies). We need to first query A and B and then send the processed result to C before replying to the client.
This means that our interesting givens will be the values returned from A and B and our captured inputs and outputs will contain the input into C.

 
So let's have a look at how Systems A and B return the values previously saved in the interesting givens to the application and also how System C captures the input.

For this example, I created a class called FakeServerTemplate.java which contains the boiler plate code that is necessary to create an embedded server. Each System A, B and C will inherit from it and provide specific handler implementations.

 public abstract class FakeSystemTemplate {  
   private final HttpServer server;  
   protected InterestingGivens givens;  
   protected CapturedInputAndOutputs captures;  
   public FakeSystemTemplate(int port, String context,InterestingGivens givens, CapturedInputAndOutputs captures) throws IOException {  
     this.givens = givens;  
     this.captures = captures;  
     InetSocketAddress socketAddress = new InetSocketAddress(port);  
     server = HttpServer.create(socketAddress,0);  
     server.createContext(context, customHandler());  
     server.start();  
   }  
   public abstract HttpHandler customHandler();  
   public void stopServer() {  
     server.stop(0);  
   }  
 }  


Latter, when we create the acceptance test we will see how we will pass the interesting givens and the captured inputs and outputs to the Systems.
Systems A and B will return the values stored in the interesting givens using a unique key(Latter we will see how this keys are set in the givens).


 public class SystemA extends FakeSystemTemplate {  
   public SystemA(int port, String context, InterestingGivens interestingGivens, CapturedInputAndOutputs capturedInputAndOutputs) throws IOException {  
     super(port, context, interestingGivens, capturedInputAndOutputs);  
   }  
   @Override  
   public HttpHandler customHandler() {  
     return httpExchange -> {  
       String response = givens.getType("system A returns", String.class);  
       httpExchange.sendResponseHeaders(200, response.length());  
       OutputStream outputStream = httpExchange.getResponseBody();  
       outputStream.write(response.getBytes());  
       outputStream.close();  
       httpExchange.close();  
       captures.add("output from system A", response);  
     };  
   }  
 } 
 
 public class SystemB extends FakeSystemTemplate {  
   public SystemB(int port, String context, InterestingGivens interestingGivens, CapturedInputAndOutputs capturedInputAndOutputs) throws IOException {  
     super(port, context, interestingGivens, capturedInputAndOutputs);  
   }  
   @Override  
   public HttpHandler customHandler() {  
     return httpExchange -> {  
       String response = givens.getType("system B returns", String.class);  
       httpExchange.sendResponseHeaders(200, response.length());  
       OutputStream outputStream = httpExchange.getResponseBody();  
       outputStream.write(response.getBytes());  
       outputStream.close();  
       httpExchange.close();  
       captures.add("output from system B", response);  
     };  
   }  
 }  


For system C we will be capturing the arriving input.

 public class SystemC extends FakeSystemTemplate {  
   public SystemC(int port, String context, InterestingGivens interestingGivens, CapturedInputAndOutputs capturedInputAndOutputs) throws IOException {  
     super(port, context, interestingGivens, capturedInputAndOutputs);  
   }  
   @Override  
   public HttpHandler customHandler() {  
     return httpExchange -> {  
       Scanner scanner = new Scanner(httpExchange.getRequestBody());  
       String receivedMessage = "";  
       while(scanner.hasNext()) {  
         receivedMessage += scanner.next();  
       }  
       scanner.close();  
       httpExchange.sendResponseHeaders(200, 0);  
       httpExchange.close();  
       captures.add("system C received value", receivedMessage);  
     };  
   }  
 }  


Now that our remote systems are ready, lets write our test.


 @RunWith(SpecRunner.class)  
 public class KnownOddNumbersTest extends TestState {  
   private SystemA systemA;  
   private SystemB systemB;  
   private SystemC systemC;  
   private Application application;  
   @Before  
   public void setUp() throws Exception {  
     systemA = new SystemA(9996, "/", interestingGivens, capturedInputAndOutputs);  
     systemB = new SystemB(9997, "/", interestingGivens, capturedInputAndOutputs);  
     systemC = new SystemC(9998, "/", interestingGivens, capturedInputAndOutputs);  
     application = new Application(9999, "/");  
   }  
   @After  
   public void tearDown() throws Exception {  
     systemA.stopServer();  
     systemB.stopServer();  
     systemC.stopServer();  
     application.stopApplication();  
   }  
   @Test  
   public void shouldReceiveResultWhenARequestIsSentToTheApplication() throws Exception {  
     given(systemARepliesWithNumbers("1,2,3"));  
     and(systemBRepliesWithNumbers("4,5,6"));  
     when(aRequestIsSentToTheApplication());  
     then(theApplicationReturnedValue(), is("1,3,5"));  
     then(systemCReceivedValue(),is("1,3,5"));  
   }  
 }  


By extending TestState.java we get acces to the interestingGivens and capturedInputsAndOutputs objects. We will pass them to the remote systems, this way Systems A and B will be aware of what we expect them to return and also C will be able to capture its input.

The methods used inside given(), and(), when() then() are just static fixture methods. I think it good to avoid making long classes so that's why the test class just contains the test, everything else is extracted into reusable fixture methods. Lets have a look at them.


 public class GivensFixture {  
   public static GivensBuilder systemARepliesWithNumbers(String numbers) {  
     return givens -> {  
       givens.add("system A returns", numbers);  
       return givens;  
     };  
   }  
   public static GivensBuilder systemBRepliesWithNumbers(String numbers) {  
     return givens -> {  
       givens.add("system B returns", numbers);  
       return givens;  
     };  
   }
 
  public class WhenFixture {  
   public static ActionUnderTest aRequestIsSentToTheApplication() {  
     return (givens, captures) -> {  
       captures.add("application response", newClient().target("http://localhost:9999/").request().get().readEntity(String.class));  
       return captures;  
     };  
   }  
 }
 
 public class ThenFixture {  
   public static StateExtractor<String> theApplicationReturnedValue() {  
     return captures -> captures.getType("application response", String.class);  
   }  
   public static StateExtractor<String> systemCReceivedValue() {  
     return captures -> captures.getType("system C received value", String.class);  
   }  
 }  


Once we run the application, the acceptance test would go red, the next thing to do if we were parcticing ATDD, would be to go into the production code and write unit tests to guide the creation of the code that is required to make the acceptance go green. Remember the ATDD cycle.

 
The TDD of the final solution is out of the scope for this blog post, but you can find all the completed codes at this git repo:



Saturday, December 20, 2014

avoiding integration when acceptance testing

 It is a good practice to exercise the whole system(end to end) when we do an acceptance test(goos book page 8). Unfortunately sometimes we don't control 100% of the pieces that compose a system(they belong to other department, other company...), so many times we have no choice than to assume how those parts behave...

Acceptance testing its an important part of the software development process.
This types of tests are focused in testing the scenarios that are valuable for the business.  Often acceptance tests are written with a life specification framework such as JBehave, Fittnesse, Cucumber...

When testing business value the developer, needs to make sure that has understood the acceptance criteria that the business has interested in having tested.

In some companies, the acceptance criterias/specifications are prepared in a planning session prior to the development cycle, in others it is up to developers,testers and business analysts to on spot decide what needs to be acceptance tested and why.

The important thing when acceptance testing, is to express "the whats" and not "the hows". In other words focus on the overall functionality under the part of the system that is under test and not in the deep detail.

about their use and scope
Sometimes development teams forget that the acceptance tests are there not just to be evaluated automatically at build time, at the end of the day it will be Business Analysts, Quality Assurance teams or other development teams who will read them, to understand what the software does. That's why they need to be concise.

In my opinion acceptance testing should not involve integration with parts out of our control, unless its really a must. Instead should serve itself from plenty of Mocks, Stubs, Primers, Emulators, etc... in order to be able to focus in the main functionality described in the specification, that needs to be tested.

sometimes is not easy
Acceptance testing  requires dextry for develop, maintain and enhance our own domain specific text harness.

 Also, just in my opinion, as per my personal professional experience(part of it in the gambling industry) in many occasions the non deterministic nature(e.g probabilities & statistics) in which software behaves could make acceptance testing very complex. That is why, it is key to pick wisely the scenarios to test and also the edge cases.

example
Next I will show a trivial example where I will isolate and acceptance test just a part of an application which is believed to hold some business valuable. To do so I will stub all its external dependencies. We should not integration test dependencies, we should stub them and assume they work.

Let's first look at the project structure and understand what is that we are testing:

In this example it is "SomeServiceAdapter", that holds business value and we decided to write an acceptance test for it. As we will soon see the other two adapters, represent access to remote systems which are out of our control.

The "UpstreamSystemAdapter", could for example be a controller for a GUI or maybe a Rest endpoint that is used to gather data for processing.
The "TargetSystemAdapter" could for example be the entrance to a persistence layer or rest client that forwards the result of processing to another system... Whatever those dependencies are, we don't care.

Initially when we write an acceptance test nothing exists, and we need to draft our requirements by creating new classes that will represent what we want to test, and also what we want to stub.

Many developers and also frameworks, like expressing the acceptance test in a common format, known as "The Given, When, Then format". It is just a more visually friendly way of understanding a well known testing pattern called "Arrange, Act, Assert". In other words, this pattern what they try to do is helping the developer writing the test, think about the Inputs/Premises(Given/Arrange) that are passed to some action in the code under test(When/Act) and the expected results(Then/Assert).
But we not necessarily need to follow that pattern, the important thing is that we make a concise and readable test. By the way, note that I am doing this in plain Java, without any framework, my goal is just to show a demo of how acceptance test could be written, but in real life you probably would like to write that code using your favourite live spec tool so you can get a beautiful output in some html page(e.g frameworks: Yaspec, Cucumber, Spock, JBehave, Fit, Fitnesse...). Also if you use a build tool such as Jenkins or TeamCity you should be able to nicely visualise your tests.

In the following simple example, we can see an acceptance test that tests "SomeServiceAdapter" and at the same time, stubs the dependencies.

public class SomeServiceAcceptanceTest {

    private UpstreamSystemStub upstreamSystemStub = new UpstreamSystemStub();
    private TargetSystemStub targetSystem = new TargetSystemStub();
    private SomeServiceAdapter someService = new SomeServiceAdapter(upstreamSystemStub, targetSystem);

    @Test
    public void shouldCalculateTheResultGivenTheReceivedDataAndPassItToTheTargetSystem() throws Exception{
        upstreamSystemStub.sends(asList(1, 2, 3));
        someService.calculate();
        targetSystem.hasReceived(6);
    }
}

Note how the class under test has the dependencies passed to its constructor. Also note that the types defined as parameters in the constructor are also interfaces, which are implemented by both the real classes that represent the dependencies, and their respective stubs(This way we make sure that the stub fulfils the contract with what the dependency does in reality).

One of the stubs:
 public class TargetSystemStub implements TargetSystem {  
   private Integer result;  
   @Override  
   public void receivesData(Integer result) {  
     this.result = result;  
   }  
   public void hasReceived(int expected) {  
     assertThat(result, is(expected));  
   }  
 }  

The other stub:
 public class UpstreamSystemStub implements UpstreamSystem {  
   private List<Integer> data = new ArrayList<Integer>();  
   @Override  
   public List<Integer> data() {  
     return data;  
   }  
   public void sends(List<Integer> values) {  
     data.addAll(values);  
   }  
 }  

Once the test is red, we can start implementing the production code. Important to mention, that this is just a very trivial example where the production code is so simple that the production code does not require to enter a TDD cycle  but in many cases, getting to see the acceptance test green, would require also to TDD each of the bits and pieces that enable the function called from the "when" to be properly tested. Just as a side note, when that is the case we also refer to that approach as ATDD(Acceptance Test Driven Development), it involves multiple TDD cycles prior to the completion of a business valuable acceptance tests.

Here just the production implementation of the class:
 public class SomeServiceAdapter implements SomeService {  
   private final UpstreamSystem upstreamSystem;  
   private final TargetSystem targetSystem;  
   public SomeServiceAdapter(UpstreamSystem upstreamSystem, TargetSystem targetSystem) {  
     this.upstreamSystem = upstreamSystem;  
     this.targetSystem = targetSystem;  
   }  
   public Integer calculate() {  
     Integer result = upstreamSystem.data().stream().reduce(0, (n1, n2) -> n1 + n2);  
     targetSystem.receivesData(result);  
     return result;  
   }  
 }  

I guess each developer has its own technique when writing acceptance tests, I just want to mention that I recently show somebody who starts writing his acceptance tests from the "then" and I thought that was a very interesting approach, because he said that doing it that way can focus more in what exactly is expected from the system that is about to be developed, but as I said it is up to each to decide how you like writing your acceptance test, just remember that it is about the "what" and not about the "how" also pick your battles and build test harnesses(avoid integration testing as much as you can)

Here the link to the complete source code: git acceptance testing example

YOLO! :)

Friday, March 22, 2013

How do private methods affect our software testability?

 How many times did we hear the question:
“Should we test private methods?”
In this post I want to share with you my thoughts about this question and how I think we should proceed when having this doubt.
Methods with the access modifier private are code as the rest of the application, so this mean that they can potentially hide bugs.  So after a first impression my answer to that question is: “Yes, we should!”.  
Wait, a second… before you get mad at me. I want to rephrase my statement.
I think that question is completely not in place.  Instead of asking “Should we test private methods?”, we should ask: “How do private methods affect our software testability?”
Let’s consider different approaches to deal with private methods and see their pros and cons from the testability point of view:

Scenario 1 – Ok,ok you leave me no choice but reflection
This is what the official Java tutorials say about reflection: 
“Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine. This is a relatively advanced feature and should be used only by developers who have a strong grasp of the fundamentals of the language. With that caveat in mind, reflection is a powerful technique and can enable applications to perform operations which would otherwise be impossible.”
Ok, let’s  give it a try, imagine we have some private method, such as this one:



Hhmmm… So how to do this? Oh my god, do I really have to use reflection? Are you sure?
Let’s investigate a bit before making any decision.
Weeks ago I spent one full afternoon searching the internet looking for testability assurance pattern to test this in java. The only interesting discovery I did was that C# developers have a pattern for this called  “Internals Visible To Attribute”.  Unfortunately (Or maybe fortunately hehe…) that technique is not compatible with java.
There has to be an alternative, why can’t we just change the access modifier and test it normally?...
The common answer you get, when you ask that is:  You will compromise security, you will break encapsulation, you are lazy…
Ok,ok,you leave me no choice but reflection:

 Please don’t do this at your workplace J
Let’s see the Pros and Cons now.

Pros:
- The test is green and I tested the piece of code that I wanted to test
- I did not compromise the security of my software(:P Whatever….)
- I am an expert because the official java tutorials say that only cool dudes like me can use reflection.
Cons:
- A simple rename done by anybody to the method, return type or parameter will break the test and I will have to come back to rewrite the test. This type of test is very difficult to maintain.
- I broke the Security of my software. What am I talking about??? How is that possible if the method still private in the production code?? Hacking the internals of a class is a security.
- See how long that test is. Imagine you have to do this for a longer and more complex method.
More drawbacks(Taken from Java official tutorials website):



Scenario 2 – There is always a way out.
As mentioned in the previous scenario a design pattern that can help us testing private fields does not exist. But there are always ways out. Here I am going to suggest 2 and explain them:

- Protect your method: Just change the access modifier to protected. This will allow you to stub the method call and test using a pattern called Subclass & Override. Basically on your test package, you will be creating a fake that extends the class under test and then override using your expectations. You will then use that fake on your test.
This is a very common breaking dependency technique, since that private method will for sure be called somewhere else within the class and present a dependency inside other method/s(Must be broken in order to increase testability).
I don’t agree with this being a security risk because various reasons, one of them is that probably that method should not be private or, is too long to be tested indirectly, or probably that method should not even be there.
The only disadvantage I see is a decrease in the quality of the design, but I will justify that as the price we need to pay when we build software without using TDD or having testability in mind.

- Extract until you drop: Robert C. Martin in his book “Clean Code”, describes a refactoring methodology called “Extract until you drop”, the idea is refactor the code as much as possible until the point there the methods have not more than 4 lines of code. He says that a line with just a curly braces also count as a line.  If you think about it, your methods would be able to use an “if else” statement of just one line in each of the clauses.
If we want to unit test, we need to have units.  After doing this exhaustively on the method or class under test, we will probably see how that method was probably refactored into a new class, or maybe became so small that it can be tested indirectly via another method with no risk at all, since there are no longer inflection points(Places where logic of the software can potentially take a different path).
The main disadvantages of this approach will probably be that doing it probably would take too long, also on our way and specially if we are dealing with legacy code, we will need to use a lot of breaking dependency techniques and this will present a learning curve that will push us to break some of the design rules we were highly tight too in the past when the system was initially built.  But the benefit will be visible at short, mid and long term.

If you are concern about testability and you believe that testability is the path to quality in modern software, then the right question is How do private methods affect our software testability?

Sunday, March 3, 2013

The legacy code that whispered to the developer

I was practicing my legacy code refactoring skills a bit this weekend (Highly on demand in the industry lately hehe..  ;) ) when I came across this fascinating line of code:

 System.out.println("Process complete!!!");  

My first thought was: "Whatever, just another silly console output nobody cares about!"
As usual, I run my eCobertura code coverage plugin to check how I was getting on with the level of coverage.
That line was red, it didn't bother me much so I continued with the rest of my testing and I said to myself, "I will come back to it latter...".

I was almost done when my torrent software notified me that a movie just finished downloading.
Also I started to feel hungry...  I wanted to go make lunch and enjoy the movie. "Let's continue with the practice another day..." I said to myself.

After making a sandwitch I came back to my laptop with the intention of watching the movie, but my eclipse IDE was still open. And that line that eCobertura painted red, was still there looking at me:


Suddenly it started talking to me and we had a very interesting conversation:

Line 43(In a thretening tone): "Psss!... hey you!..."

Djordje: "Are you talking to me?"

Line 43: "Do you see somebody else in the room? Yes, i am talking to you" 

Djordje: "Who do you think you are taliking to like that?"

Line 43: "I am a piece of untested code in your software. If you are adding code coverage I also have the right to get some."

Djordje: "Why should I unit test you? You are just a piece of old legacy nobody cares about"

Line 43: "You are such a dumb ass, you don't get it!"

Djordje: "Get what? Leave me alone I want to enjoy my sandwitch and watch my pirate movie. Don't make an scene because I will close the IDE and I will not practice with this program never again"

Line 43: "Ok, ok... take it easy! I just want to help you. Please, let's make a deal."

Djordje: "What deal?"

Line 43: "Just spend 5 more minutes trying to unit test me and I will teach you something important."

Djordje: "Fine, just 5 minutes. This better be good, because I am very hungry"

Poor Line 43, probably it just wanted to talk to somebody. What can I learn about TDD from such a simple line of code?  Anyway I decided to make it's wish come true and paint it green with eCobertura. This is what I did:

   private PrintStream originalConsoleOutput = new PrintStream(System.out); 
   private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); 
   @Before  
   public void setUpStreams() {  
     System.setOut(new PrintStream(outContent));  
   }  
   @After  
   public void cleanUpStreams() {  
     System.setOut(originalConsoleOutput);  
   }  
      @Test  
      public void  
      when_the_process_is_complete_show_a_message  
      ()   
      {
           //..   
           statistics.process();  
           assertEquals("Processing completed!!!\n", outContent.toString());  
      }  

Basically  what I did was just asserting that the console output is the same that what the println() command has in its argument. The process() method is where Line 43 was, so its content will go to the console when statistics.process() gets executed. At the end the method @After will restore the console output to the original stream that was previously saved.


Djordje"I painted you green. Are you happy now?"

Line 43"Thank you very much!....Thanks, thanks.... I am so happy now other lines of code will not look me over the shoulder or whisper to each other. They use to say _There is Line 43, did you know that the developer who created it was drunk... I can now walk onto the compiler with my head up..."


Djordje: "Whatever!, You are green, please just be quiet. Are you leaving me alone now?..."

Line 43: "Yes I will leave you alone, bye bye..."

Djordje: "Hey wait a second!... You told me that you would tell me something important if i get you green. What is it?"

Line 43: "Sorry I almost forgot."

Djordje: "Spit it out!"

Line 43:  "Many times when working in legacy software, developers use the so called _poor man technique. They fill the code with print commands to see the contents of the objects, the problem is that they often forget to remove them. But other times there are other print commands that are valid and really are meant to be there. In occasions, it is hard to distinguish what should be tested and what should not be. The rule is: If your application outputs valid information to the console and this is the only way you can test it, then it is correct to do it. But if you can avoid testing the console or other UI's by testing some related methods(sometimes in controllers), then you don't need to test the UI's. Remember that UI's, databases, frameworks and others... should be considered just addons, to our business layer(which at the end of the day is what provides the real business value)." Djordje: "Aaaaghhh... I hate you!"

Line 43"But why?"

Djordje: "My sandwitch is cold!"

Sunday, August 26, 2012

Use a martial arts principle to improve your Test Driven Development skills.


In ancient Japan, martial arts were not just defence techniques, they were also  a way of life(jap. budo”).
In this way of life they combined physical, moral and spiritual dimensions with the goal of self-improvement.

Since very young, Japanese kids would join a martial arts school, to study: karate, aikido, judo…  
They learned martial arts using a technique called “Kata”.

The “Kata” technique was based in the principle of “learn by repetition”.
By practicing exercises in a repetitive maner the learner  comes to a point where develops the ability to execute those exercises and movements in a natural and reflexive maner(“intuition”).

Today in software development the amount of trainers that recommend to use Test Driven Development Katas, is increasing.  Some would even say that the TDD katas, are the only way to learn TDD.  The original idea of the kata as a maner of learning software development was introduced by Dave Thomas(author of: The pragmatic Programmer: From Journey man to Master ).

Programming principles such as KISS(Keep It Simple and Stupid) or YAGNI(You Ain’t Gonna Need It ) are very common in the TDD philosophy, but the main mantra behind TDD is the RGR principle (Red, Green, Refactor).

From the theoretical point of view, the RGR principle seems often very simple to new TDD developers.
But when it comes to real life practice, in many occasions the complexity of the software can make less experienced developers to panic.

A great practice to avoid this is to practice a TDD kata once in a while.
Peter Norvost(author of the blog: Geek Noise), recommends to new TDD developers to do simple katas of 30 minutes every morning for 2 weeks. 
Now I will show you an example of a very simple TDD kata and then I will perform a demonstration.

KATA #1: THE STRING CALCULATOR (Kata description taken from: http://osherove.com/tdd-kata-1/)
1-An empty string returns zero
2-A single number returns the value
3-Two numbers, comma delimited, returns the sum
4-Two numbers, newline delimited, returns the sum
5-Three numbers, delimited either way, returns the sum
6-Negative numbers throw an exception
7-Numbers greater than 1000 are ignored



Note: Don't forget to set the quality to HD in the video player





Share with your friends