Fork me on GitHub

What is Quality-Check?

The goal of Quality-Check is to provide a small Java library for basic runtime code quality checks. It provides similar features to org.springframework.util.Assert [1] or com.google.common.base.Preconditions [2] without the need to include big libraries or frameworks such as Spring or Guava. The package Quality-Check tries to replace these libraries and provide all the basic code quality checks you need. (If you're familiar with those classes, just look at our comparison page.)

The checks provided here are typically used to validate method parameters and detect errors during runtime. To detect errors before runtime we use JSR-305 Annotations. With these annotations you are able to detect possible bugs earlier. For more informations look at FindBugs™ JSR-305 support.

We think that our module is particularly suitable for APIs, which contain their own domain objects and services that are validated using Quality-Check not only functionally, but also technically. More over we provide an easy to use fail-fast description of an API to immediately report at its interface any failure or condition that is likely to lead to failure.

We noticed that many projects just copy org.springframework.util.Assert or com.google.common.base.Preconditions to get access to these quality checks. Therefore we provide these features and a small library that can be included in any application without big overhead.

Why is it called check and not assertion?

We think that checks of method arguments are not only assertion tests it's more over a condition to work properly. Beyond this, it supports you to write faster contracts for your methods and classes. If nothing of this package make sense look at the concept design by contract.

Example

/**
 * Sets the given object if it is not null.
 *
 * @throws IllegalArgumentException
 *         if the given argument is {@code null}
 */
setObject(final Object object) {
	if (object != null) {
		throw new IllegalArgumentException("Argument 'object' must not be null.");
	}
	this.object = object;
}

can be replaces by:

/**
 * Sets the given object if it is not null.
 */
@ArgumentsChecked
setObject(final Object object) {
	this.object = Check.notNull(object);
}

Why use Quality-Checks for your method parameters?

Quality-Check brings several advantages to your project. If used extensivel throughout your codebase, you will benefit from the following points. We will outline each one in a short paragraph below.

  • Prevent technical errors due to invalid input parameters
  • Detect errors early, where they occur
  • Do not waste time by writing useless test to cover error detection branches
  • No need to document exceptions thrown because of invalid method arguments

Prevent errors

Quality-Checks to check the input arguments of a method, such as Check.isNull(object) or Check.positionIndex(4, myList.size()) should be applied to every argument of every public method in your class, service or component. Why is that? If you check all arguments as soon as they are passed to your code, you do not need to deal with invalid argument values through the rest of your component or class. For example, if every public method ensures that no null values are passed to the class, you do not have to care about null values in your private methods.

Therefore, Quality-Checks assist you in preventing technical errors in your classes, because they only have to work with valid arguments.

Detect errors early

Often, in Java development, you have to deal with NullPointerExceptions or other faults which can be tracked back to invalid values passed to methods and handed further down till they crash in your code. Sometimes it is hard to trace down where the invalid value came from. To identify invalid values as soon as possible and detect errors where they occur, we suggest to guard every public method with Quality-Checks.

Using quality checks, erroneous input arguments are identified, as soon as they are passed to your component.

Avoid useless tests

If you add checks for method arguments manually, you will notice that you have to write additional tests using invalid method arguments to cover these branches. One example for a manual check is here:

void doSomething(final List<String> list) {
	if( list == null ) {
		throw new IllegalArgumentException("Argument 'list' must not be null.");
	}
	if( list.isEmpty() ) {
		throw new IllegalArgumentException("Argument 'list' must not be empty.");
	}
}

In this example, you would have to write two additional tests (one with a null list and one with an empty list), just to test these to branches - or, if you do not, your branch coverage will go down.

Quality-Checks will save you from doing so! As calls to Check.* are method calls you will cover them in any test automatically. We make sure that Quality-Check works, so that you do not have to test it. See the example below:

@ArgumentsChecked
void doSomething(final List<String> list) {
   	Check.isNull(list, "list");
	Check.isEmpty(list, "list");
}

No need to write documentation for technical error cases

Similar to the example of the branch coverage, you also write a lot of JavaDoc documentation for exceptions thrown in your methods, which check for illegal input parameters.

/**
 * Method does something.
 *
 * @throws IllegalArgumentException if list is null.
 * @throws AnotherIllegalArgumentException if list is empty.
 */
void doSomething(final List<String> list) {
	if( list == null ) {
		throw new IllegalArgumentException("Argument 'list' must not be null.");
	}
	if( list.isEmpty() ) {
		throw new AnotherIllegalArgumentException("Argument 'list' must not be empty.");
	}
}

As quality check throws the exceptions and your code does not there is no need for you to document these exceptions. You can focus on the real important documentation of exceptions which might be thrown by business logic. To show the caller of the method that quality-checks are in place and certain exceptions might be thrown, we add an @ArgumentsChecked annotation.

Overview over the Quality-Check way

Contribute

  • Report bugs, feature requests and other issues in the issue tracking application.
  • Help with the documentation by pointing out areas that are lacking or unclear, and if you are so inclined, submitting patches to correct it. You can quickly contribute rough thoughts by forking this project on GitHub or downloading at Sourceforge , or you can volunteer to help collate and organize information that is already there.
  • Some software metrics can be found on our Continuous Integration server at Buildhive or Ohloh.

Your participation in this project is much appreciated!