A good commit message can make a difference!

Some developers have a habit of committing their code without a clear commit message.

I was one of them! Now, I consider that to be a bad habit.

With time I realized that it is hard to remember the intention of an old commit by just looking at the code. It becomes even impossible when reviewing a colleagues’ code.

In this post, I will be sharing a template message I adopted with one of my previous teams.

For simplicity, I will be referring to one of my commits to a fork of the GildedRose-Refactoring-Kata on my GitHub account.

Message Template

Below is the template. As you can see, it is split into four colors. In the next part of the blog, I will break down the message to explain each of its sections separately.

[Issue Tracker #] One-line summary of the commit description 

Why is this change necessary? 
  - Detailed description 1
  - Detailed description 2
  ... 

Section I – ‘[Issue Tracker #]’:

Between the two brackets, I write the issue number corresponding to this commit. The format here varies depending on which issue tracking system I am using (ex: [ProjectName-123] for Jira and [#123] for Github.)

Message so far

[#5] One-line summary of the commit description   

Why is this change necessary? 
   - Detailed description 1 
   - Detailed description 2 
   ... 

Section II – ‘One-line summary of the commit description’:

In the second section, I try to summarize the full commit in just one sentence. Failing to do so means that my commit is doing more than one task and needs to be broken down.

Message so far

[#5] Move the constants out of the GildedRose class

Why is this change necessary? 
   - Detailed description 1 
   - Detailed description 2 
   ... 

Section III – ‘Why is this change necessary’: 

In this line, I try to answer the question ‘Why is this change necessary?’ In most cases, this line is a copy of the ‘Issue Title’.

Message so far

[#5] Move the constants out of the GildedRose class 

In order to, refactor and clean the code of GildedRose
   - Detailed description 1 
   - Detailed description 2 
   ... 

Section IV – ‘Detailed Description’:

Finally, I replace the items of the list in this section with a detailed description of the important technical changes I did in the code. Here I try to think of what I should remember if I was to read this message a couple of months ahead.

The final commit message looks like

[#5] Move the constants out of the GildedRose class 

In order to, refactor and clean the code of GildedRose
   - Make MAX_QUALITY, MIN_QUALITY & MIN_SELL_IN_DATE as local variables ItemVisitor
   - Move AGED_BRIE string to the AgedBrie class
   - Move SULFURAS string to the Sulfuras class
   - Move CONCERT string to the Concert class
   - Adapt the tests accordingly

By just reading this last message, anyone should deduce that firstly, in this commit I only moved some constants from the GildedRose class. And secondly, the commit was part of a larger code refactoring of the GildedRose class.

How is this helpful?

So, why do I consider this to be helpful?

Here are my reasons:

  1. Forces me to code in baby steps and thus have small commits.
  2. By having small commits, it would be easier, later on, to track down bugs.
  3. Makes code review easier and faster
  4. Most SCMs and tracking tools are now integrated, that makes linking commits to an issue seamless. This link has 2 benefits:
    1. By just adding the ‘Issue Number‘ in the message, I can refer to the issue’s details to view all the corresponding commits.
    2. Limits my development to only the features and bugs in the project’s backlog. I won’t be submitting any useless code.
  5. Serves as a documentation for my code. More than once, I referred to those messages when writing a detailed technical report of our product.

Finally…

At first, it was a bit annoying to write this message for each commit. But as we realized its benefits, it became a habit for us!

You don’t have to adopt this exact message, you can come up with any format you think is good for you as long as it is clear and concise.

Enjoy coding ūüôā

Tutorial: How to configure maven surefire plugin work with JUnit 5

Recently, I had a task to migrate the unit tests in our project from ‘JUnit 4’ to ‘JUnit 5’. As many developers, I researched a bit to learn about the major differences between the two versions and drafted a plan for smooth migration.

From the first look, I thought my only job was refactoring the tests and probably some helper classes. But, I was wrong! I ran into a configuration issue with the maven-surefire-plugin configuration.

In this post, I will be sharing the encountered issue and its fix. Note that I will not cover the detailed steps of how to migrate from ‘JUnit 4’ to ‘JUnit 5’.

Tests run: 0!

We, as many other developers, use the maven-surefire-plugin¬†to run our tests during the test phase of maven’s build lifecycle. We rely heavily on this plugin because it fails the build when one of the tests is broken!

With JUnit4, everything was working perfectly! But after the migration, the plugin was always reporting that not tests are run:

'Tests run: 0, Failures: 0, Errors: 0, Skipped: 0 ...'!

Calculator Class

For the purpose of this blog, let us assume we want to build a Calculator. For now, we only have the ‘add‘ method implemented as shown below.

Calculator.java

public final class Calculator {
    public static int add(int firstNumber, int secondNumber) {
        return firstNumber + secondNumber;
    }
}

JUnit 4 Code

junit4

I will start with the ‘JUnit 4’ version of the code.

pom.xml

We need to depend on the junit artifacts and add the plugin for the surefire. Here is the required pom file:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

CalculatorTest.java

In the test class, we have one test that asserts our method is doing the correct addition.

import org.junit.Assert;
import org.junit.Test;

public class CalculatorTest {
    @Test
    public void
    our_calculator_should_add_2_numbers() {
        Assert.assertEquals(5, Calculator.add(2, 3));
    }
}

Build Output

Now, if we try to run ‘mvn clean install‘ on the above pom file we get the below output:

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running CalculatorTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.037 sec - in CalculatorTest

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

****
[INFO] --------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] --------------------------------------------------

Everything works perfectly!

JUnit 5 Code

junit5

It’s time to migrate our code to ‘JUnit 5’!

pom.xml

The first step is changing our dependencies in the pom file.

Some significant changes were applied to the ‘Junit 5’ dependency metadata. The framework functionalities have been split into several artifacts:

  • junit-jupiter-api
  • junit-jupiter-engine
  • junit-platform-suite-api
  • junit-jupiter-params
  • junit-platform-surefire-provider

For this simple example, it is enough to depend on ‘junit-jupiter-engine‘ & ‘junit-platform-surefire-provider‘.

So, our pom becomes:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.0.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-surefire-provider</artifactId>
        <version>1.0.0</version>
     </dependency>
</dependencies>

P.S. Check ‘JUnit 5 User Guide‘ if you are interested in more details on the ‘JUnit 5’ artifacts

CalculatorTest.java

A good portion of the code in tests has to be changed to migrate to ‘JUnit 5’. Again, I am not going to cover those changes in this blog.

For the simple test we have written before, we need to change two things:

  1. Change the import statements
  2. Change the assertion call
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class CalculatorTest {
    @Test
    public void
    our_calculator_should_add_2_numbers() {
        Assertions.assertEquals(5, Calculator.add(2, 3));
    }
}

Build Output

Although the ‘mvn clean install‘ command is still returning a ‘BUILD SUCCESS‘ message, it is actually¬†not running any tests which make the whole build process suspicious.

This is our issue!

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running CalculatorTest
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec - in CalculatorTest

Results :

Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

****
[INFO] ------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------

The Fix

The fix of this problem is simple, need to modify the build section in our pom to add the 2 dependencies to the ‘maven-surefire-plugin‘¬† plugin section as shown below.

By doing so, we forced the maven-surefire-plugin to use the latest JUnit artifacts and thus run the JUnit 5 tests.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.0.0</version>
                </dependency>
                <dependency>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter-engine</artifactId>
                    <version>5.0.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

Running ‘mvn clean install‘ will return the correct output now:

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running CalculatorTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 sec - in CalculatorTest

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

****
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

 

I hope this blog post would save you some time when migrating to ‘JUnit 5’!

Good luck ūüôā

How to become a better developer!

The fast and constant change in technology made it inevitable for developers to always improve their skills through continuous learning. It is a fact now that developers with outdated skills will be left behind!
Learning isn’t the same for everyone. Some people may learn well by themselves; some may need instruction and example. In the programming world, many resources can meet those particular needs.
And using skills on projects that aren’t all imaginary is key too. Real world projects equal real world experience that translates into adapting more efficient, effective programming language.
What else helps to improve programmers’ skills and help them continue to move into the next wave-whatever that may be? I found this graphic that explains tactics, solutions, and ideas to pursue.
Personally, I have been following some of those for the past couple of years to improve my technical and soft skills!

Click to Enlarge Image

’8

My takeaways from a TDD debate between Cope & Uncle Bob

As a developer, there is a high chance that you had a debate on the value of TDD in building software, especially if you apply it!

I had a lot of those debates!

A couple of months ago, I came across such a debate between Jim Coplien and Robert Martin (Uncle Bob). I found this discussion kind of interesting especially that it involves two leaders in software engineering.

You can watch the debate here:

Takeaways

Here are my takeaways from the discussion:

Three Rules of TDD

Uncle Bob defines the following three rules for applying TDD:

  1. Don’t write a line of production code without having a corresponding failing test
  2. Don’t write too many failing tests without writing production code
  3. Don’t write more production code than is sufficient to pass the currently failing test

Architecture is Important

Jim points out that he has no problem with those rules, his concerns are more architecture related. Jim and Uncle Bob would argue for more than ten minutes to finally reach an agreement on the importance of architecture. The below five points summarizes what they agreed on:

  1. Architecture is very important
  2. It is entirely wrong to assume that the code will assemble itself magically just by writing a lot of tests and doing quick iterations
  3. Design evolves with time and should be assembled one bit at a time
  4. An Object should have properties to give it meaning. At the beginning, those properties should be minimal.
  5. Architecture shouldn’t be created based on speculation

TDD and Professionalism

Probably the only disagreement you can sense from this¬†debate is what defines¬†a professional¬†software engineer.¬†For Uncle Bob, it is irresponsible for a software engineer to deliver a single line of code without writing a unit test for it.¬†Jim, on the other hand, considers ‘Design by Contract’ to be¬†more powerful than TDD.

My Point of View!

Personally, I have been applying TDD since I joined my team three years ago. After experiencing the benefits of this practice, we got to a point where we don’t write or refactor any line of code without having a¬†corresponding unit test!

In addition to that, I had the chance to coach other developers by running coding dojo sessions at work.

All that makes me say that I agree more with Uncle Bob on the topic of professionalism!

References
  1. Coplien and Martin Debate TDD, CDD and Professionalism

How to handle Java exceptions in clean code? – Part 1

Reading the chapter ‘Error Handling‘ from the book ‘Clean Code‘ made me think whether developers follow the clean code rules when writing production code. It also appeared to me that the difference between the Java exception types might not clear be for some!

The purpose of this short tutorial is to clarify those two points. And to make it clearer, I will be dividing it into two posts. In the first one, I will explain the different types of Java exceptions. Whereas in the second one, I will show how to write clean exception code!

Java Exceptions

In Java, the class Throwable is at the top of the class hierarchy of all exceptions. The classes Error and Exception directly extend Throwable. All the subclasses of Error and Exception are grouped into two types ‘Checked Exceptions‘ and ‘UnChecked Exceptions‘as displayed in the image below.

javaexceptiondiagram

What is the difference between Checked and UnChecked Exceptions?

UnChecked Exceptions

UnChecked Exceptions extend the classes ‘Error‘ or ‘RuntimeException‘. In this case, developers don’t have to worry about catching or handling the exceptions at compile time as the compiler won’t report any error. But, as they are not caught, those exceptions may result in complete failure of the application when thrown during execution.

Below are two examples of UnChecked Exceptions!

1. Runtime Exception

The below method simply divides two numbers:

private static int divide(int numerator, int denominator) {
    return numerator / denominator;
}

The code is fine and will compile with no errors! So what is the problem?

The problem might occur at runtime if we try to call the method while passing zero as the denominator. Since this exception is not caught, our system will crash throwing the below arithmetic exception:

Exception in thread "main" java.lang.ArithmeticException: / by zero
 at MainUnCheckedException.divide(MainUnCheckedException.java:7) ...
2. Error

The below method compiles, but since I missed writing the base cases calling the method will crash the system and throw a StackOverflowError (as shown below) will throw an Error!

private static int fibonacci(int number) {
    return fibonacci(number - 1) + fibonacci(number - 2);
}
Exception in thread "main" java.lang.StackOverflowError
 at MainUnCheckedException.fibonacci(MainUnCheckedException.java:10)...

Checked Exceptions

On the other hand, all other classes extending the ‘Exception‘ class are considered to be Checked Exceptions. In this case, the code will not compile if the developer doesn’t explicitly handle the exception.

This adds a level of security to your code, as you are forced to specify how your code should behave when an exception occurs and thus decreases the chance of having an unrecoverable failure in the system.

Let’s see an example!

public class MainCheckedException {
    public static void main(String[] args) {
        FileInputStream fileInputStream = new FileInputStream("foo.txt");
    }
}

Error:(6, 43) java: unreported exception java.io.FileNotFoundException;
must be caught or declared to be thrown

In the above code, we are trying to read a file ‘foo.txt’, but our compiler complains that we need to handle the FileNotFoundException.

Solving this compilation error can be done in two ways:

  1. Try Catch: The first solution requires surrounding the code with a try-catch.
    private static void readFileTryCatch() {
        try {
            FileInputStream fooFile = new FileInputStream("foo.txt");
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        }
    }

    Even if the file was not there, this code would not break thanks to the try-catch. As shown in the below code and output, the system will print out the exception and continue execution!

    public static void main(String[] args) {
        readFileTryCatch();
        System.out.println("Done");
    }
    ------------Output------------
    foo.txt (No such file or directory)
    Done
  2. Throw an exception: The other solution is adding a ‘throws FileNotFoundException‘ to the method signature.
    private static void readFileThrow() throws FileNotFoundException {
        new FileInputStream("foo.txt");
    }

    Using this solution will propagate handling the exception to the calling methods as illustrated in the two options below:
    Option 1: Adding throws to all methods signatures 

    public static void main(String[] args) throws FileNotFoundException {
        readFileThrow();
        System.out.println("Done");
    }
    ------------Output------------
    Exception in thread "main" java.io.FileNotFoundException: foo.txt (No such file or directory)
    at java.io.FileInputStream.open0(Native Method) ...

    Option 2: Catching the exception in one of the methods in the call stack

    public static void main(String[] args)  {
        try {
            readFileThrow();
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        }
        System.out.println("Done");
    }
    ------------Output------------
    foo.txt (No such file or directory)
    Done

 

I hope this post gave you a better understanding of Java exceptions! In the 2nd part, I will be sharing more details on how to properly write exceptions in clean code and which of the two exception types to use!

Extreme Practices – Agile Tour Beirut

In my previous post, I shared with you how Philippe¬†and I prepared for our talk “Extreme Practices.” In this post, I will be briefing the talk’s content; starting with the pitch and ending with the feedback! Philippe has already posted a blog on the talk that you can read¬†here.

Pitching

dsc_0444-1

Each of the speakers had to brief their session in a thirty seconds pitch. This was mine:

This is unusual for me, because my co-presenter is in Paris! Philippe and I will demonstrate how we adopted the practices of Extreme Programming in our distributed team. We will also have two live demos; the first on remote pair programming and the second on remote meetings.

The talk

The audience started taking their seats; and in a couple of minutes, the room was full! We started by engaging the audience with three simple questions!

Who goes to work by car?

Who goes to work by bus?

Who goes to work on Skype?

Extreme programming

After introducing ourselves, our team and Murex, we spent the first half of the talk discussing four of the XP practices and their benefits.

  1. Ten Minutes Build
    • Helps developers stay¬†focused on what they are doing
    • Shorten the feedback loop
    • Encourages developers to submit frequently thus resulting in easier bug analysis
  2. TDD
    • Only coding what makes tests pass decreases the possibility of generating bugs
    • In most cases, a failing unit test is enough to detect where the bug is and thus reducing the need for debugging
    • The refactoring step drives to clean code
    • Finding difficulty¬†writing a test is an indication that¬†refactoring is required
  3. Pair Programming
    • Benefits:
      • Newcomers tend to learn faster and submit on their first day
      • The quality of our code has increased
      • We didn’t notice any negative any impact on productivity
      • It helped us build a bonded team
    • Difficulties
      • It is very tiring for both the driver and navigator
      • It is risky because some developers¬†prefer to work alone
  4. Retrospectives: For this part, we explained the five stages of our retrospectives
    • Check-in/energizer
    • Throwback
    • Collect insights & discuss
    • Actions
    • ROTI

Extreme programming in remote mode

Our second half of the talk was dedicated to sharing how we are applying XP in a remote mode, mainly focusing on Pair-Programing and Retrospectives. The discussion included the difficulties we faced at the beginning and how we managed to solve them. We ended the discussion on both topics by a live demo!

  1. Remote Pair Programming
    • To overcome the problem of time difference between the two cities, the pairs tend to share their calendars as well as an online document with the detailed tasks required to finish the story
    • The navigator might easily lose focus; that is why we try to submit frequently and switch control as much as possible
    • It is more tiring than local pair-programming especially if you have the headset on all day long. We agreed that anyone is free to ask for a break at any time
  2. Remote Retrospectives
    • The whiteBoards were located in Paris, and thus it was hard for us in Beirut to effectively contribute to the meetings. We managed to solve this problem by replacing our the whiteboard with an online Trello boards.
    • Initially, our meetings were held over the phone lacking any visualization of the team on the other side which caused a lot of frustration. To overcome this problem, our IT team installed Visio Conference rooms in both cities!

Here is a short video of the PairProgramming demo we did!

Main message

You don’t have to move abroad for your dream job!“.

Remote work is becoming the trend! The advancement of the collaboration tools and technologies is making it easier for companies to adopt. In the future, you will see more and more developers working from home.

That was our message to the audience!  We concluded that there are three ways to organize your team when working remotely:

  1. Split the team in two if there are enough members in each city
  2. Work in open-source mode if team members are distributed over many cities
  3. Finally, adopt our remote XP practices if it is not possible to split the team in two

Feedback

Kudo.png

In addition to the above two Kudo cards, I received several positive verbal feedback at the end of the session. All that was a sign that our talk was successful!

Slides

Finally, you can have a look on our slides here:

 

Extreme Practices – The Preparation

Extreme Practices was the name of the talk Philippe and I gave at the AgileTour in Beirut on 15th of October, which based on the feedback was a successful one! Our main focus was on the practices of extreme programming and how to adopt them in a distributed team.

As this was my first talk, I decided to write two blog posts about it. In this first blog, I will be sharing the preparation whereas in the second post (in few days) I will be talking about the talk itself.

It all started with a discussion

Earlier this year, I attended a workshop organized by Pierre Hervouet who is also the organizer of AgileTourBeirut. After the session, we had a lengthy discussion on how we are applying Extreme Programming in our distributed team. We ended that conversation by agreeing that I give a talk at the AgileTour on that subject.

The next day I discussed with Philippe¬†the possibility of him being my co-speaker. Unfortunately, visiting Beirut during that time wasn’t possible for Philippe! But later it struck us; why not giving the presentation in a remote mode (i.e. I will be in Beirut while he is in Paris) to simulate how we work on a daily basis.

That kicked off the preparation for the talk!

The content

After a couple of brainstorming sessions, we defined our presentation’s content and agreed that having live demos of remote pair programming and remote retrospective would make the talk more valuable!

Here is the content we agreed on:

  1. Introduction of ourselves and our team
  2. A short definition of XP
  3. A detailed explanation of some XP practices (below) and how we are applying them
    1. 10 minutes build
    2. TDD (Test Driven Development)
    3. Pair Programming
    4. Retrospectives
  4. A short story on how we started the distributed team
  5. Remote pair programming
    1. Explain how we are doing it
    2. Discuss the difficulties we faced and how we managed to solve them
    3. Do a live demo and solve parts of the FizzBuzz problem
  6. Remote retrospectives
    1. A couple of stories on how we initially started doing remote meetings
    2. Again, mention all the difficulties and the respective solution
    3. Do a live demo
  7. Final message
  8. Answer questions

The next step was building up the presentation slides and preparing the demos!

Slides design

We are both software developers. Thus we have limited design skills plus we usually are busy at work and can’t spend a lot of time on the design. That is why we requested the help of our Internal Communications team in the Paris office! The team focused on enhancing the slides’ background¬†and images, but the content was not modified. After a couple of iterations with them, we ended up with¬†very well designed and beautiful slides!

The below images show a sample of the difference!

Presentation coach

I usually give talks, presentations and even training sessions at work, but this was my first attempt to give a talk at a conference. Yes, I was a bit worried about it! Thus, we asked for training with a professional coach from our training department in Paris.

We had two sessions with the trainer. The first one was in Paris (i.e. we were both in the same room) whereas the second one simulated the real scenario of the talk (i.e. I was in Beirut and Philippe in Paris).

The coach’s focus was on:

  1. The¬†talk’s timing, to make sure that we don’t pass our allocated time. That led to the removal of some slides that were less relevance to the main message.
  2. The content, to make sure our message is well received by the audience. This led to the rewriting of parts of our text.
  3. Our presentation skills, which included how I stand on the stage, eye contact with the audience and Philippe’s intervention during the talk.

I have to say that this training was essential to the success of our talk! Some of the key points I learned from this training were:

  1. It is ok to forget and thus don’t hesitate to look at the notes if needed
  2. Limit the notes to headlines instead of full text
  3. Try not to look at the big screen
  4. Keep eye contact with all the audience

A big risk

Let’s admit, doing a remote presentation especially with an unstable connection as we have in Beirut is a huge risk! But we were well prepared!

Again here, I asked for help. But this time it was from the IT department at AUB¬†(the tour’s host). They were very helpful, as they granted me a dedicated link with (relatively) high-speed Internet and performed two rehearsals to make sure everything is working as expected. (I took the below image from the last rehearsal)

To avoid any surprises during the talk, Philippe and I decided to record the two demos ahead of time and just play them if needed. Below you can check the two recorded demos.

Pair-programming recording

Retrospective recording

 

The preparation for the talk took a lot of time and was tiring, but it was worth as everything paid off at the end!

Stay tuned; next post is coming soon!