TLDR: Learn Java by taking advantage of code completion and JavaDoc in the IDE to explore classes with JUnit Tests
I my book Java For Testers I encourage the reader to experiment when learning Java by writing small JUnit tests to explore classes. I’m going to expand on that concept in this blog post and the associated video.
Exploratory Programing
I’ve been using the term Exploratory Programming to describe the following:
- choose a library or class to explore
- write a JUnit Test Class
- write small JUnit @Test methods which explore functionality on the class or library
- use the IDE code completion to see what methods are available and explore the interface
- use the IDE ability to view JavaDoc to learn more from the offical documentation
- write assertions to validate your assumptions about the interface
Why Exploratory Programming?
If you adopt the above approaches then you can take a self-directed learning approach to expand on the information in books and courses.
If a book or course tries to comprehensively cover all the functionality in a library or class then it would be far too big and unreadable so we have to augment our reading with exploration.
If you only rely on the exercises in a book or course then you will have a small subset of use cases and experience to draw upon.
How to Explore with Programming?
I show an example in the associated video but I’ll briefly explain here.
Create an exploration @Test
method
If I start with a class I want to explore e.g. ArrayList
The first thing I’ll do is create an @Test
that allows me to explore. e.g.
@Test
public void canExploreArrayList(){
ArrayList<String> strings= new ArrayList<>();
}
This very simple @Test
method achieves quite a lot:
- use the IDE to import the appropriate class
- force adding any library as a dependency to maven
- create some ‘documentation’ as I go
Note that:
I code to the physical class first i.e. ArrayList
because at this point, I don’t know what interface it implements.
- I can use click-through to view the code i.e. in IntelliJ IDE
ctrl+click
orcmd+click
on the classname - read the code and I can see what Interfaces it implements
- I can then explore those and see if I should be coding to an interface or a concrete class
- Then I change and code to the Interface where possible
- I will typically do this after I have explored the concrete class because then I have a better understanding
Create @Test
methods around assumptions
Once I start exploring the interface through code completion i.e. strings.
I can read the JavaDocs for the methods ctlr+J
(mac) or
ctrl+q
(windows).
Then I can choose methods that seem interesting and start experimenting with them. Making sure that I can write assertions that validate my assumptions about the method or help me document the functionality.
Why @Test
and not a main
method?
I’ve seen a lof of videos on YouTube where all the examples and tutorials are driven by main
methods, but I think this is the wrong approach.
By using @Test
methods:
- I can use the method name to document my thoughts
- I keep practicing TDD
- I write small focused code i.e. I don’t have 1
main
method, I have many exploratory@Test
methods - I can continually refactor into smaller
private
methods if I want - my code becomes self documenting through
@Test
names, assertions and private method names - it is easy to run individual
@Test
methods from the IDE and run all the methods if I want - I don’t have to create a new project for each exploration - just add a new
Test
class
When I code - the main
method is one of the last things I write. I very often create tools with no main
method until I need to package it for someone else to use. And the main
method tends to call a single entry point class which I will have previously have wrapped with an @Test
method for my prototyping.
I suggest you get in the habit of driving your code and your exploratory learning of coding via @Test
methods.
How else can you learn?
You can learn to code via Katas or interview questions that you find online.
I think if you get in the habit of taking a TDD approach to those then it will also look better if you are faced with such a problem in an interview session. And it forces you to think through a problem in small chunks.
You can also take a case study approach of trying to use a library to achieve an end result. Much of my github.com/eviltester/testtoolhub tool was built using this approach.
I like to combine all the approaches:
- exploratory programming
- katas and interview questions
- case studies
When I encourage the reader in my book Java For Testers to explore or experiment. This is what I mean.
Video
I expand on the above material in the following video so you can see the approach in action.
https://www.youtube.com/watch?v=DjcsFWPHQP0