On refactoring an hidden technical dept

Can you accumulate technical dept, even if you regularly clean up your sources meticulously? A short while ago I would have said that this is possible but unlikely. That was before I started taking on the migration of all of OpenFastTrace‘s unit tests from JUnit4 to JUnit5.

Like most non-trivial projects OFT accumulated quite a number of unit tests over the years and although it was always the plan to move to JUnit5 some day, they were all written for JUnit4.  With the arrival of OFT 2.0.0 — which also was a major refactoring endeavor — I felt now would be the perfect time to make that migration happen. After all I was in the refactoring flow.

To rule them all…

Shouldn’t take long, right? Boy was I mistaken. The one thing I completely underestimated was how dependent many of our integration tests were on JUnit rules like Stefan Birkner’s “JUnit System Rules“. While getting the dependencies right in the Maven POM was only slightly harder than anticipated, migrating all parts where rules were used took way longer. I quickly found a replacement for the “Temporary Folder API“: JUnit Pioneer’s “TempDirectory Extension“.

Homebrew extensions

I did not find a suitable replacement of the JUnit System Rules though, so I decided to take matters into my own hands and create the “JUnit5 System Extensions“. At the time of this writing they cover System.out, System.err and System.exit assertions.

It was a good if also painful practice for writing JUnit5 extensions. Only later I realized that Stefan seems to have started a port of his rules, but it did not look finished to me. Anyway this gave me the opportunity to dive deeper into the JUnit 5 life cycle.

Run baby, run baby, run baby, run!

Christoph was the one who pointed out to me, that the tests I wrote only ran in Eclipse but were silently skipped when triggered by Maven. The culprit was an older version of the Surefire plugin for Maven. Turns out that you need 2.22.1.

Simply beautiful

Even though the migration turned out to be much more of a pain than anticipated, especially integration tests and test that check for exceptions looks much nicer thanks to JUnit5. It’s about time for this upgrade and I am sure we won’t regret this when writing new tests.

OpenFastTrace 2.0.0 released

This release is a big step forward. One new feature, a few small fixes and a lot of code improvements that gives us a much cleaner and more uniform API, better test coverage and lower overall complexity.

But a new API also means we had to break backward compatibility to achieve something that the existing API would not allow since it had a separation of report and export mode: you can now reuse an import that already ran to create both reports and exports from it without redoing the import. This is a considerable speed-up (and we call the project OpenFastTrace for a reason. Runtime efficiency was and will always be one of our main design principles.

You can find examples of how to use the API in the user guide and in OFTs own code of course.

Thanks to Christoph for his patience during his review of the giant change set that the API rework caused!

Enjoy the new and improved API.

Happy tracing.

OpenFastTrace Gradle plugin 0.4.0 released

Today we released version 0.4.0 of the OpenFastTrace Gradle plugin. This is the first version that can be considered production ready. It was successfully integrated into a real life commercial project using the following features:

  • Software architecture design (Swad) imported as a dependency from a maven repository
  • Software detailed design (Swdd) written in MarkDown
  • Coverage tags in code (long format) for item types src, utest and stest
  • Filter requirements from Swad, Swdd and Code using a artifact type filter
  • Filter Swad requirements relevant for the project using a tag filter
  • Generate a tracing report in text format containing failure details
  • Additionally to the report we export the requirements in Specobject format that can be delivered to integration for creating an overall tracing report

Only minor adaptions were required and OFT works in parallel to the proprietary tracing tool. It is just must faster 😉

To see how you can integrate the OFT Gradle plugin into your project have a look at the example projects.

Speed up Writing OFT Specifications With WikiText Templates for Eclipse

Starting today we will provide a growing set of Eclipse templates to help speed-up writing OpenFastTrace specifications using the Eclipse IDE. Using these templates also has the nice side-effect of reducing the chance for errors when writing specifications.

Find the templates here: https://github.com/itsallcode/openfasttrace-eclipse-templates

Improving test coverage in log message

Log message test coverage for the java.util.logging.Logger depends on the log level by default. As an optimization the lambda functions that constitute log messages are only executed if the configured log level is higher or equal the log message level.

In effect this means that for optimum test coverage you would have to set the log level to FINEST for your unit tests. But that will spam your console or log files.

Thankfully the designers thought of that issue and provided a means to use multiple log consumers in parallel. Christoph created a NoOpLoggingHandler and added it to the list of log consumers in the logging.properties of the JUnit tests.

This makes sure all lambdas are called and we get maximum test coverage.

If you want to learn more check out the documentation of the LogManager class.

Release letters – useful for users but a coupling nightmare for developers

Release letters are useful. No doubt about that.

They are the go-to place for users who want to know what’s new in a software release.

Granted that information is already available in your projects ticket system but you can’t expect your users to dig through tickets just to be up-to-date.

So you duplicate information. Which is unsatisfying because it creates coupling:

  • You copy information from the features and bug fixes from the tickets
  • You add links to the ticket system
  • You copy the version number
  • and you should not forget to enter the right release date shortly before you release

In some of our commercial projects we had this process automated to a high degree. The only thing really missing was translating the tech talk from the tickets into short descriptions that are helpful for your users.

We need to reach that point.

 

Publishing to Maven Central

We already publish openfasttrace to JCenter, see openfasttrace distribution. Using libraries from JCenter in a Gradle build only requires adding repositories { jcenter() } to your build.gradle.

You can do the same with maven by adding the following to your pom.xml:

<repositories>
  <repository>
    <id>central</id>
    <name>bintray</name>
    <url>http://jcenter.bintray.com</url>
  </repository>
</repositories>

But we want to make it even easier for maven users by publishing our artifacts to the Maven Central repository which maven uses by default.

The easiest way to publish to Maven Central is synchronization via bintray. The setup process is not trivial, so I want to share my experience.

  1. Apply for a repository for your organisation (in our case: org.itsallcode)
  2. Optionally generate a gpg key without password and upload it to bintray. As an alternative you can also use bintray’s key.
  3. Configure your bintray maven repository to automatically sign uploaded files
  4. Make sure your project conforms to Maven Central’s quality requirements:
    1. Your pom.xml must contain information about the project license and developers (elements <licenses> and <developers>)
    2. Publish the source code by adding this to your pom.xml:
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>3.0.1</version>
        <executions>
          <execution>
            <id>attach-sources</id>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    3. Publish javadoc by adding this to pom.xml:
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>3.0.1</version>
        <executions>
          <execution>
            <id>attach-javadocs</id>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
  5. Now you can publish your artifacts to JCenter as usual via mvn deploy. Don’t forget to increment your version number in pom.xml.
  6. The last step is to synchronize the artifacts by clicking the “Sync” button in the “Maven Central” tab in bintray. If everything was OK after some time you should see the message “Successfully synced and closed repo”.

Then it will take some time (in my case around 40 minutes) until your packages are shown in Maven Central and you can search for it. And then it will take up to two hours until you can find them at search.maven.org.

Named vs. Numeric Requirement IDs

With every new project there will be a discussion whether requirement IDs should have a unique name or simply a numbering scheme.

If you look at OFT‘s specification document, you will see that we chose named IDs. The reason in our case is quite simple: we use the ID as reference in OFT’s native specification format (aka. “requirement-enhanced Markdown”) and it is a lot simpler to understand the connections between the specification items in different artifact types if you can tell by the name what the requirement ID is about. It also helps debugging.

That being said there are major drawbacks with this approach:

  1. You have to think of and type an ID for every requirements
  2. In large collections of requirements you might need hierarchical ID parts to make the IDs unique (like req~import.full-coverage-tag-format~1)
  3. Sometimes you pick bad names and are forced to decide whether to bulk-change all documents or live with the name
  4. Some tools (like Doors for example) enforce numeric IDs.

Bottom line: deciding between named and numeric IDs a task that you should think long and hard about before you start your project.

Good news is OFT supports both flavors.