Friday, 17 July 2015

Using for checking code on github

I run all the tests for Java For Testers prior to releasing the book. Since all code shown in the book is pulled out of the source, it should mean that all the source code you see in the book should run.
I thought it would be useful to have a second execution of the code after it has been released to github. (I have the code with all annotations I need to 'pull' chunks out, in a different repo, then release the code with annotations removed, to github) looked like a potential candidate since it seemed pretty simple to setup.
With, all I had to do was authenticate with my github credentials, then select the Java For Testers code repo:
The first thing travis told me was that I didn't have a .travis.yml file, so I read the instructions on the site, and it couldn't find my file. Since the .travis.yml file needs to be in the root of the repo.
language: java
mvn test
After moving the .travis.yml file to the root, I tried again. Of course, I had mis-read the instructions so I removed mvn test from the .yml file.
language: java
I found the yaml file validator useful at this point. And used it for all future changes.
And then, since my src folder is not at the root of the repo, since I might need to release other assets along with the code to support the book. Well, couldn't find the pom.xml.
I added a build line into the .travis.yml file
language: java
script: mvn test -f ./source/pom.xml
And now everything started building. With a few failing @Test methods.
See the @Test methods in Java For Testers aren't strictly unit tests, so they do interact with the file system and create files. And some of the examples have hard coded paths which readers will be able to amend, and which work fine on my local machine, but which fail on In theory, I could probably amend the examples in the book, but that might make them a little more complicated and confusing. And since this CI run is a 'secondary' check, I decided instead to exclude the File tests from the build.
(I will probably try and learn more about Travis-CI and revisit this decision in the future) And rather than using JUnit suites to do this, I simple excluded them via maven configuration in the plugins section.
    <!-- exclude file tests from execution -->
see inclusion-exclusion on the maven site for more details.
Of course, now I needed to create a new pom.xml purely, but that was easy enough so now my .travis.yml file looks as follows:
language: java
script: mvn test -f ./source/travis-ci-pom.xml
And at this point, I get to see that some of my exercise answer code has some locale dependency. Specifically in the calendar exploration.
I originally wrote an answer to one of my examples as follows:
public void experimentWithCalendarConstants(){
  Calendar cal = Calendar.getInstance();
  cal.set(2013, Calendar.DECEMBER, 15, 23,39, 54);

  assertThat(cal.get(Calendar.DAY_OF_WEEK), is(1));
  assertThat(cal.get(Calendar.DAY_OF_WEEK), is(Calendar.SUNDAY));
  assertThat(cal.get(Calendar.WEEK_OF_MONTH), is(2));
  assertThat(cal.get(Calendar.WEEK_OF_YEAR), is(50));
  assertThat(cal.get(Calendar.DAY_OF_YEAR), is(349));
I specifically avoided instantiating Calendar with locale examples because I thought it would introduce additional complexity into the code, but of course, isn't based in the UK so has a different set of date defaults, which only become apparent when using the WEEK_OF_MONTH and WEEK_OF_YEAR calculations.
So I added additional configuration into the example to control the First Day of Week and Minimal Days In First Week
If I was going to make the code robust then I'd really set the locale properly. e.g. per this stackoverflow example
I chose to make the code in the book simple, knowing that it was primarily going to guide the creation of code to support testing, and that code normally runs under fairly tight configuration. i.e. it doesn't go out and have to run on multiple devices and lots of operating systems. And if your test code does, then it is at that point that you usually learn to handle the platform differences that are relevant for you specific execution context.
Since has the facility to easily build against multiple JDKs, yes, I took advantage of that too.
  - oraclejdk8
  - oraclejdk7
  - openjdk7
This is something that I didn't do locally, so is a handy bonus for the build.
All told, I found this a useful experiment and exercise. And now I have a secondary build to help, and you can see the status of that build on