public static void main(String[] args) {
...
}
It's quick, it's easy, and it gets the job done. And if I had to choose 1 philosophy it would be "Pick the quickest and easiest effective way to get the job done." JUnit fits perfectly with this philosophy. It makes unit testing code even shorter than "main", and introduces useful features to boot. It can really make unit testing fun and hassle free.
Today I will go over the 4 JUnit 4 annotations that I use the most: BeforeClass, Test, Ignore, and AfterClass.
i. Including JUnit 4 in your project
Before we can do anything we need to create a project and include JUnit 4 in its build path. The easiest way to do this is to annotate a method with @Test, mouse over the error and click Import 'Test' (org.junit). Remember: quick; easy.
ii. Running the test
Right click > Run As > JUnit Test
(or Alt + Shift + X, T but c'mon)
And now we move on to the actual annotations
1. @Test
The most important one, of course, is @Test. Testing is the whole point. Methods annotated with @Test are essentially substitutes for "main". For instance, in
package baldwin.testerator;
import org.junit.Test;
public class John {
@Test
public void sayHello() {
System.out.println("Hello, old friend.");
}
}
Your old friend John will greet you thus:
Hello, old friend.
Nice, simple, effective.
Protip! If you have multiple methods with @Test, JUnit does not guarantee any kind of execution order.
2. @BeforeClass
Now, suppose you want to do something before your tests are run. There are many times when you would want to do this. Off the top of my head I can think of: instantiating local variables like Lists, opening and initializing database connections, configuring logging, and several others.
See below:
package baldwin.testerator;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.junit.BeforeClass;
import org.junit.Test;
public class John {
static Logger log = Logger.getLogger(John.class);
@BeforeClass
public static void init() {
BasicConfigurator.configure();
log.info("Long time no see!");
}
@Test
public void sayHello() {
log.info("Hello, old friend.");
}
}
You'll notice that our friend John has acquired some bling in the form of a Log4j Logger. This allows him to say things to you in a sophisticated manner. Now he greets you like this:
0 [main] INFO baldwin.testerator.John - Long time no see! 1 [main] INFO baldwin.testerator.John - Hello, old friend.How pretentious! This logging behavior is enabled by the command
BasicConfigurator.configure();which tells Log4j to output the most basic of logging information into the Console. Any method annotated with @BeforeClass will be executed at the beginning of your test, Before any @Test methods:
package baldwin.testerator;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.junit.BeforeClass;
import org.junit.Test;
public class John {
static Logger log = Logger.getLogger(John.class);
@BeforeClass
public static void init() {
BasicConfigurator.configure();
log.info("Long time no see!");
}
@Test
public void sayHello() {
log.info("Hello, old friend.");
}
@Test
public void commentOnAppearance() {
log.info("Wow, you have gained weight.");
}
}
Produces:
0 [main] INFO baldwin.testerator.John - Long time no see! 3 [main] INFO baldwin.testerator.John - Hello, old friend. 4 [main] INFO baldwin.testerator.John - Wow, you have gained weight.
I am starting to regret running into John after all these years.
Protip! JUnit requires @BeforeClass methods to be static. Otherwise you'll get an initializationError.
Tip: JUnit has another annotation, @Before, which will be executed once before every @Test method invocation. I don't use it nearly as much.
3. @Ignore
@Ignore does what you expect it to do. It makes JUnit ignore the annotated @Test method. In our case, it allows John to be a bit more tactful:
@Test @Ignore
public void commentOnAppearance() {
log.info("Wow, you have gained weight.");
}
Produces:
0 [main] INFO baldwin.testerator.John - Long time no see! 3 [main] INFO baldwin.testerator.John - Hello, old friend.Tip: @Ignore is Ignored by anything other than @Test methods. A @BeforeClass @Ignore method will still be executed, for instance.
4. @AfterClass
Finally, @AfterClass is the post-testing equivalent of @BeforeClass. You can use it to close database connections, summarize data, or anything really that you might want to do once you've completed all your tests.
We have completed our chat with John and he says goodbye:
package baldwin.testerator;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
public class John {
static Logger log = Logger.getLogger(John.class);
@BeforeClass
public static void init() {
BasicConfigurator.configure();
log.info("Long time no see!");
}
@Test
public void sayHello() {
log.info("Hello, old friend.");
}
@Test @Ignore
public void commentOnAppearance() {
log.info("Wow, you have gained weight.");
}
@AfterClass
public static void sayGoodbye() {
log.info("Goodbye, stay in touch!");
}
}
0 [main] INFO baldwin.testerator.John - Long time no see! 5 [main] INFO baldwin.testerator.John - Hello, old friend. 7 [main] INFO baldwin.testerator.John - Goodbye, stay in touch!
Tip: As with @BeforeClass, methods with this annotation must also be static.
Tip: As with @BeforeClass, @AfterClass has a son called @After who has ADHD and demands to be called after every @Test method. I usually ignore this annotation.
Well, wasn't that heartwarming?
Until next time, John. Until next time.

No comments:
Post a Comment