Chapter Three - Writing Your First Java Code

In this chapter we will take a slightly different approach. We will advance step-by-step through the chapter and we will write a simple method which we will run as a JUnit test.

My First JUnit Test

The code will calculate the answer to “2+2”, and then assert that the answer is “4”.

The code we write will be very simple, and will look like the following:

 1 package com.javafortesters.chap003myfirsttest.examples;
 2 import org.junit.Test;
 3 import static org.junit.Assert.assertEquals;
 4 
 5 public class MyFirstTest {
 6 
 7     @Test
 8     public void canAddTwoPlusTwo(){
 9         int answer = 2+2;
10         assertEquals("2+2=4", 4, answer );
11     }
12 }

I’m showing you this now, so you have an understanding of what we are working towards. If you get stuck, you can refer back to this final state and compare it with your current state to help resolve any problems.

Prerequisites

I’m assuming that you have followed the setup chapter and have the following in place:

  • JDK Installed
  • IDE Installed
  • Maven Installed
  • Created a project
  • Added JUnit to the project pom.xml

We are going to add all the code we create in this book to the project you have created.

Create A JUnit Test Class

The first thing we have to do is create a class, to which we will add our JUnit test method.

A class is the basic building block for our Java code. So we want to create a class called MyFirstTest.

The name MyFirstTest has some very important features.

  • It starts with an uppercase letter
  • It has the word Test at the end
  • It uses camel case

It starts with an uppercase letter because, by convention, Java classes start with an uppercase letter. By convention means that it doesn’t have to. You won’t see Java throw any errors if you name the class myFirstTest with a lowercase letter. When you run the code, Java won’t complain.

But everyone that you work with will.

We expect Java classes to start with an uppercase letter because they are proper names.

Trust me.

Get in the habit of naming your classes with the first letter in uppercase. Then when you read code you can tell the difference between a class and a variable, and you’ll expect the same from code that other people have written.

It has the word Test at the end. We can take advantage of the ‘out of the box’ Maven functionality to run our JUnit tests from the command line, instead of the IDE, by typing mvn test. This might not seem important now, but at some point we are going to want to run our code automatically as part of a build process. And we can make that easier if we add Test in the Class name, either as the start of the class name, or at the end. By naming our classes in this way, Maven will automatically run our JUnit test classes at the appropriate part of the build process.

It uses camel case where each ‘word’ in a string of concatenated words starts with an uppercase letter. This again is a Java convention, it is not enforced by the compiler. But people reading your code will expect to see it written like this.

To create the class

In the IDE, open up the Project hierarchy so that you can see the src\test\java branch and the src\main\java branch. The Project hierarchy is shown be default as the tree structure on the left of the screen, and you can make if visible (if you close it) by selecting the Project button shown vertically on the left of the IntelliJ GUI.

My project hierarchy looks like this:

+ javaForTesters
  + .idea
  + src
    + main
      + java
      + resources
    + test
      + java

.idea is the IntelliJ folder, so I can ignore that.

I right click on the java folder under test and select the New \ Java Class menu item.

Or, I could click on the java folder under test and use the keyboard shortcut alt + insert, and select Java Class (on a Mac use ctrl + n)

Type in the name of the Java class that you want to create i.e. MyFirstTest and select [OK]

Don’t worry about the package structure for now. We can easily manually move our code around later. Or have IntelliJ move it around for us using refactoring.

Template code

You might find that you have a code block of comments which IntelliJ added automatically

/**
 * Created with IntelliJ IDEA.
 * User: Alan
 * Date: 24/04/13
 * Time: 11:48
 * To change this template use File | Settings | File Templates.
 */

You can ignore this code as it is a comment. You can delete all those lines if you want to.

Add the class to a package

IntelliJ will have created an empty class for us. e.g.

public class MyFirstTest {
}

And since we didn’t specify a package, it will be at the root level of our test\java hierarchy.

We have two ways of creating a package and then moving the class into it:

  • Manually create the package and drag and drop the class into it
  • Add the package statement into our code and have IntelliJ move the class

Manually create the package and drag and drop the class into it by right clicking on the java folder under test and selecting New \ Package, then enter the package name you want to create.

For this book, I’m going to suggest that you use the top level package structure:

  • com.javafortesters

And then name any sub structures as required. So for this class we could create a package called com.javafortesters.chap003myfirsttest.examples. You don’t have to use the chap003 prefix, but it might help you trace your code back to the chapter in the book. I use this convention to help you find the example and exercise source code in the source download.

If we want to, we can add the package statement into our code and have IntelliJ move the class:

Add the following line as the first line in the class:

package com.javafortesters.chap003myfirsttest.examples;

The semi-colon at the end of the line is important because Java statements end with a semi-colon.

IntelliJ will highlight this line with a red underscore because our class is not in a folder structure that represents that package.

IntelliJ can do more than just tell us what our problems are, it can also fix this problem for us if we click the mouse in the underscored text, and then press the keys alt + return.

IntelliJ will show a pop up menu which will offer us the option to:

Move to package com.javafortesters.chap003myfirsttest.examples

Select this option and IntelliJ will automatically move the class to the correct location.

The Empty Class Explained

package com.javafortesters.chap003myfirsttest.examples;
public class MyFirstTest {
}

If you’ve followed along then you will have an empty class, in the correct package and the Project window will show a directory structure that matches the package hierarchy you have created.

Package Statement

The package statement is a line of code which defines the package that this class belongs in.

package com.javafortesters.chap003myfirsttest.examples;

When we want to use this class in our later code then we would import the class from this package.

The package maps on to the physical folder structure beneath your src\test folder. So if you look in explorer under your project folder you will see that the package is actually a nested set of folders.

+ src
  + test
    + java

And underneath the java folder you will have a folder structure that represents the package structure.

+ com
  + javafortesters
    + chap003myfirsttest
      + examples

Java classes only have to be uniquely named within a package. So I could create another class called MyFirstTest and place it into a different package in my source tree and Java would not complain. I would simply have to import the correct package structure to get the correct version of the class.

Class Declaration

The following lines, are our class declaration.

public class MyFirstTest {
}

We have to declare a class before we use it. And when we do so, we are also defining the rules about how other classes can use it too.

Here the class has public scope. This means that any class, in any package, can use this class if they import it.

When we create classes that will be used for JUnit tests, we need to make them public so that JUnit can use them.

The { and } are block markers. The opening brace { delimits the start of a block, and the closing brace } delimits the end of a block.

All the code that we write for a class has to go between the opening and closing block that represents the class body.

In this case the class body is empty, because we haven’t written any code yet, but we still need to have the block markers, otherwise it will be invalid Java syntax and your IDE will flag the code as being in error.

Create a Method

We are going to create a method to add two numbers. Specifically 2+2.

I create a new method by typing out the method declaration:

    public void canAddTwoPlusTwo(){
    }

Remember, the method declaration is enclosed inside the class body block:

public class MyFirstTest {

    public void canAddTwoPlusTwo(){
    }
}
  • public

This method is declared as public meaning that any class that can use MyFirstTest can call the method.

When we use JUnit, any method that we want to use as a JUnit test should be declared as public.

  • void

The void means that the method does not return a value when it is called. We will cover this in detail later, but as a general rule, if you are going to make a method a JUnit test, you probably want to declare it as void.

  • ()

Every method declaration has to define what parameters the method can be called with. At the moment we haven’t explained what this means because our method doesn’t take any parameters, and so after the method name we have “()”, the open and close parentheses. If we did have any parameters they would be declared inside these parentheses.

  • {}

In order to write code in a method we add it in the code block of the method body i.e. inside the opening and closing braces.

We haven’t written any code in the method yet, so the code block is empty.

Make the method a JUnit test

We can make the method a JUnit test. By annotating it with @Test.

In this book we will learn how to use annotations. We rarely have to create custom annotations when automating, so we won’t cover how to create your own annotations in this book.

JUnit implements a few annotations that we will learn. The first, and most fundamental, is the @Test annotation. JUnit only runs the methods which are annotated with @Test as JUnit tests. We can have additional methods in our classes without the annotation, and JUnit will not try and run those.

Because the @Test annotation comes with JUnit we have to import it into our code.

When you type @Test on the line before the method declaration. The IDE will highlight it as an error.

    @Test
    public void canAddTwoPlusTwo(){
    }

When we click on the line with the error and press the key combination alt + return then we will receive an option to:

Import Class

Choosing that option will result in IntelliJ adding the import statement into our class.

import org.junit.Test;

We have to make sure that we look at the list of import options carefully. Sometimes we will be offered multiple options, because there may be many classes with the same name, where the difference is the package they have been placed into.

Calculate the sum

To actually calculate the sum 2+2 I will need to create a variable, then I can store the result of the calculation in the variable.

        int answer = 2+2;

Variables are a symbol which represent some other value. In programming, we use them to store values: strings, integers etc. so that we can use them and amend them during the program code.

I will create a variable called answer.

I will make the variable an ‘int’. int declares the type of variable. int is short for integer and is a primitive type, so doesn’t have a lot of functionality other than storing an integer value for us. An int is not a class so doesn’t have any methods.

The symbol 2 in the code is called a numeric literal, or an integer literal.

        int minimumInt = -2147483648;
        int maximumInt = 2147483647;

When I create the variable I will set it to 2+2.

Java will do the calculation for us because I have used the + operator. The + operator will act on two int operands and return a result. i.e. it will add 2 and 2 and return the value 4 which will be stored in the int variable answer.

Assert the value

The next thing we have to do is assert the value.

        assertEquals("2+2=4", 4, answer );

When we write @Test methods we have to make sure that we assert something because we want to make sure that our code reports failures to us automatically.

An assert is a special type of check:

  • If the check fails then the assert throws an assertion error and our method will fail.
  • If the check passes then the assert doesn’t have any side-effects

The asserts we will initially use in our code come from the JUnit Assert package.

So when I type the assert, IntelliJ will show the statement as being in error, because I haven’t imported the assertEquals method or Assert class from JUnit.

To fix the error I will alt + return on the assertEquals statement and choose to:

static import method...

from

Assert.assertEquals in the org.junit package

IntelliJ will then add the correct import statement into my code.

import static org.junit.Assert.assertEquals;

The assertEquals method is polymorphic. Which simply means that it can be used with different types of parameters.

I have chosen to use a form of:

        assertEquals("2+2=4", 4, answer );

Where:

  • assertEquals is an assert that checks if two values are equal
  • "2+2=4" is a message that is displayed if the assert fails.
  • 4 is an int literal that represents the expected value, i.e. I expect 2+2 to equal 4
  • answer is the int variable which has the actual value I want to check against the expected value

I could have written the assert as:

        assertEquals(4, answer );

In this form, I have not added a message, so if the assert fails there are fewer clues telling me what should happen, and in some cases I might even have to add a comment in the code to explain what the assert does.

I try to remember to add a message when I use the JUnit assert methods because it makes the code easier to read and helps me when asserts do fail.

Note that in both forms, the expected result is the parameter, before the actual result.

If you get these the wrong way round then JUnit won’t throw an error, since it doesn’t know what you intended, but the output from a failed assert would mislead you. e.g. if I accidentally wrote 2+3 when initializing the int answer, and I put the expected and actual result the wrong way round, then the output would say something like:

java.lang.AssertionError: 2+2=4 expected:<5> but was:<4>

And that would confuse me, because I would expect 2+2 to equal 4.

Run the @Test method

Now that we have written the method, it is time to run the method and make sure it passes.

To do that either:

Run all the @Test annotated methods in the class

  • right click on the class name in the Project Hierarchy and select:
    • Run 'MyFirstTest'
  • click on the class in the Project Hierarchy and press the key combination:
    • ctrl + shift + F10
  • right click on the class name in the code editor and select:
    • Run 'MyFirstTest'

Run a single @Test annotated method in the class

  • right click on the method name in the code editor and select:
    • Run 'canAddTwoPlusTwo()'
  • click on the method name in the code editor and press the key combination:
    • ctrl + shift + F10

Since we only have one @Test annotated method at the moment they will both achieve the same result, but when you have more than one @Test annotated method in the class then the ability to run individual methods, rather than all the methods in the class can come in very handy.

Run all the @Test annotated methods from the command line

If you know how to use the command line on your computer, and change directory then you can also run the @Test annotated methods from the command line using the command:

  • mvn test

To do this:

  • open a command prompt,
  • ensure that you are in the same folder as the root of your project. i.e the same folder as your pom.xml file
  • run the command mvn test

You should see the annotated methods run and the Maven output to the command line.

Summary

That was a fairly involved explanation of a very simple JUnit test class:

 1 package com.javafortesters.chap003myfirsttest.examples;
 2 import org.junit.Test;
 3 import static org.junit.Assert.assertEquals;
 4 
 5 public class MyFirstTest {
 6 
 7     @Test
 8     public void canAddTwoPlusTwo(){
 9         int answer = 2+2;
10         assertEquals("2+2=4", 4, answer );
11     }
12 }

Hopefully when you read the code now, it all makes sense, and you can feel confident that you can start creating your own simple self contained tests.

This book differs from normal presentations of Java, because they would start with creating simple applications which you run from the command line.

When we write automation code, we spend a lot of time working in the IDE and running the @Test annotated methods from the IDE, so we code and run Java slightly differently than if you were writing an application.

This also means that you will learn Java concepts in a slightly different order than other books, but everything you learn will be instantly usable, rather than learning things that you are not likely to use very often in the real world.

Although there is not a lot of code, we have covered the basics of a lot of important Java concepts.

  • Ordering classes into packages
  • Importing classes from packages to use them
  • Creating and naming classes
  • Creating methods
  • Creating a JUnit Test
  • Adding an assertion to a JUnit test
  • Running @Test annotated methods from the IDE
  • primitive types
  • basic arithmetic operators
  • an introduction to Java variables
  • Java comments
  • Java statements
  • Java blocks

You also encountered the following IntelliJ shortcut keys:

Function Windows Mac
Create New alt + insert ctrl + n
Intention Actions alt + enter alt + enter
Intention Actions alt + return alt + return
Run JUnit Test ctrl + shift + F10 ctrl + shift + F10

And now that you know the basics, we can proceed faster through the next sections.