Project

General

Profile

Feature #1888

Feature #1886: implement a unit testing framework

integrate the framework into the build

Added by Greg Shah over 11 years ago. Updated about 3 years ago.

Status:
Closed
Priority:
Normal
Target version:
-
Start date:
Due date:
% Done:

100%

Estimated time:
16.00 h
billable:
No
vendor_id:
GCD

History

#1 Updated by Greg Shah over 7 years ago

  • Target version deleted (24)

#2 Updated by Vladimir Tsichevski about 3 years ago

  • Status changed from New to WIP
  • Assignee set to Vladimir Tsichevski

It is quite easy to create a Gradle-based project with unit-test for FWD.

The only thing necessary to enable test is to add a dependency on the unit-testing framework, for example:

dependencies {
    testImplementation 'junit:junit:4.13.1'
}

After this done, the tests can be run with:

gradle test

The complete build.gradle for a project may look like this:

apply plugin: 'java'
apply plugin: 'maven'

group = 'com.goldencode'
version = '0.0.1-SNAPSHOT'

description = """FWD unit-testing""" 

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
   mavenCentral()
   mavenLocal()
}

dependencies {
    compile (group: 'com.goldencode', name: 'p2j', version:'4.0.fwd-SNAPSHOT') {
        exclude group: 'com.bea.xml', module: 'jsr173-ri'
    }
    testImplementation 'junit:junit:4.13.1'
}

Note: in this example FWD need to be build and installed in local Maven repository.

Note1: in the example project, I used the standard Maven-style source directory structure, so Gradle knows where to find tests already.

#3 Updated by Greg Shah about 3 years ago

Note: in this example FWD need to be build and installed in local Maven repository.

We deliberately picked Gradle and avoided Maven. I don't want to add a dependency on a local Maven repo for testing.

Note1: in the example project, I used the standard Maven-style source directory structure, so Gradle knows where to find tests already.

This was another thing we deliberately avoided by choosing Gradle. I don't want to shift to a standard Maven source directory structure.

Is there an advantage to having a separate Gradle build for testing? I prefer to just add testing support to our existing Gradle build.

#4 Updated by Vladimir Tsichevski about 3 years ago

The reason I did this in a project other than FWD so far is I failed to add tests into the FWD build process. The 'test' task is supported by the 'java' plugin, and FWD gradle build is based on ant, which seems to be mutual exclusive with 'java'.

#5 Updated by Vladimir Tsichevski about 3 years ago

BTW is there a reason such a mix of ant and gradle was created instead of using gradle only?

#6 Updated by Hynek Cihlar about 3 years ago

Vladimir Tsichevski wrote:

The reason I did this in a project other than FWD so far is I failed to add tests into the FWD build process. The 'test' task is supported by the 'java' plugin, and FWD gradle build is based on ant, which seems to be mutual exclusive with 'java'.

Create a simple Gradle java target and run ConsoleLauncher class from JUnit 5.

#7 Updated by Greg Shah about 3 years ago

We started the project in 2004 with ant. We only shifted to Gradle in 2017. At that time we decided to add dependency processing in Gradle but to not rewrite all of the ant build since there was little advantage and lots of work needed.

We would like to have a full Gradle build, remove ant, but it just takes time.

#8 Updated by Hynek Cihlar about 3 years ago

Vladimir Tsichevski wrote:

BTW is there a reason such a mix of ant and gradle was created instead of using gradle only?

This is a temporal state, we should eventually move the Ant stuff to Gradle, too.

#9 Updated by Vladimir Tsichevski about 3 years ago

Hynek Cihlar wrote:

Create a simple Gradle java target and run ConsoleLauncher class from JUnit 5.

I am not fluent with Gradle, could you provide an example, please. Note also: the 'java' plugin is not available in FWD gradle build.

#10 Updated by Hynek Cihlar about 3 years ago

Vladimir Tsichevski wrote:

Hynek Cihlar wrote:

Create a simple Gradle java target and run ConsoleLauncher class from JUnit 5.

I am not fluent with Gradle, could you provide an example, please. Note also: the 'java' plugin is not available in FWD gradle build.

Try something like the following,

task test(type: JavaExec) {
  classpath = configurations.fwdAllRuntime
  main = 'org.junit.platform.console.ConsoleLauncher'
  args '<see the docs for ConsoleLauncher>'
}

You will need to add dependency on JUnit 5 including junit-platform-console-standalone.

Also new Gradle configuration (extending fwdAllRuntime) should be added so that the JUnit (and its transitive dependencies) don't get deployed in production. Those JUnit dependencies should be added to this new configuration and the configuration used in the test task.

#11 Updated by Vladimir Tsichevski about 3 years ago

Hynek Cihlar wrote:

You will need to add dependency on JUnit 5 including junit-platform-console-standalone.

Also new Gradle configuration (extending fwdAllRuntime) should be added so that the JUnit (and its transitive dependencies) don't get deployed in production. Those JUnit dependencies should be added to this new configuration and the configuration used in the test task.

Thanks, Hynek, it works for me now.

Now we shall decide on the test tree source location and structure. Any ideas?

#12 Updated by Greg Shah about 3 years ago

Please put the test classes into the same package as the classes they test, but with a test base directory instead of src. This means that unit tests for src/com/goldencode/p2j/util/date.java would be in test/com/goldencode/p2j/util/date.java.

I know and accept that this different from the standard Maven layout, but we already deviate. I prefer to be a deviant. :)

#13 Updated by Vladimir Tsichevski about 3 years ago

Greg Shah wrote:

I know and accept that this different from the standard Maven layout, but we already deviate. I prefer to be a deviant. :)

I prefer to use bicycles rather than invent them :)

#14 Updated by Vladimir Tsichevski about 3 years ago

Greg Shah wrote:

Please put the test classes into the same package as the classes they test, but with a test base directory instead of src. This means that unit tests for src/com/goldencode/p2j/util/date.java would be in test/com/goldencode/p2j/util/date.java.

We will need additional classes with common support for testing. We can use something like com.goldencode.p2j.tests as the base package name for that classes, OK?

#15 Updated by Greg Shah about 3 years ago

We can use something like com.goldencode.p2j.tests as the base package name for that classes, OK?

For any test helpers that have dependencies upon FWD, put them in com.goldencode.p2j.testing. For anything generic, please put the helpers in com.goldencode.testing.

I don't want to use the package name tests since this suggests that the classes are in fact tests themselves.

#16 Updated by Vladimir Tsichevski about 3 years ago

Greg Shah wrote:

... For anything generic, please put the helpers in com.goldencode.testing.

By anything generic do you mean OE-related? For example, where the OE error numbers and messages shall go?

#17 Updated by Greg Shah about 3 years ago

4GL (OE) related stuff is FWD-specific so that is NOT generic.

#18 Updated by Greg Shah about 3 years ago

By generic, I mean that the code would be used in other projects outside of FWD.

#19 Updated by Vladimir Tsichevski about 3 years ago

  • % Done changed from 0 to 80
  • Status changed from WIP to Review

JUnit-based testing support was added in 3821c rev. 12130.

Also 139 tests in 13 containers for parsing/applying various formats were added.

#20 Updated by Greg Shah about 3 years ago

Code Review Task Branch 3821c Revision 12130

It is good. I really only see coding standards issues.

1. Please write abstract public class AbstractFWDTest as public abstract class AbstractFWDTest.

2. Imports should use *. This affects almost all of the files.

3. Please split extends <parent> onto its own line. This affects almost all of the files.

4. Data members should use the single line form of javadoc where possible.

   /**
    * Default format string for DATETIME-TZ types.
    */
   public static final String FULL_DATETIMETZ_FORMAT = "99/99/9999 HH:MM:SS.SSS+HH:MM";

should be this:

   /** Default format string for DATETIME-TZ types. */
   public static final String FULL_DATETIMETZ_FORMAT = "99/99/9999 HH:MM:SS.SSS+HH:MM";

5. Multi-line lambdas should follow the same curly braces rules as "regular code":

protected static final Function<String, ?> makeFormat = a -> {
   ...
};

would be:

protected static final Function<String, ?> makeFormat = a ->
{
   ...
};

Single line lambdas can be protected static final Function<String, ?> makeFormat = a -> { ... };.

6. Comments inside of methods should use // instead of javadoc style.

   public void testError()
   {
      /**
       * FIXME: This must throw an exception, but it currently does not.
       * FWD formats any value with empty format to an empty string.
       */
      assertMustThrowError164(formatCharacter, "");
   }

would be:

   public void testError()
   {
      // FIXME: This must throw an exception, but it currently does not.
      //        FWD formats any value with empty format to an empty string.
      assertMustThrowError164(formatCharacter, "");
   }

7. There are quite a few methods and some data members that are missing javadoc.

8. Some javadoc is formatted with extra blank lines or doubled comments.

   /**
    * TODO: the DateFormat constructor must throw reasonable variants
    * of ErrorConditionException instead of DisplayFormatParsingException, which
    *
    * Test year is no more than 32768
    */
   /**
    * TODO: fix the date.toString: it declares
    * IllegalArgumentException, but never throws it (and must not)!
    */

   @BeforeClass
   public static void beforeClass()

should be:

   /**
    * TODO: the DateFormat constructor must throw reasonable variants
    * of ErrorConditionException instead of DisplayFormatParsingException, which
    * TODO: fix the date.toString: it declares
    * IllegalArgumentException, but never throws it (and must not)!
    *
    * Test year is no more than 32768
    */
   @BeforeClass
   public static void beforeClass()

#21 Updated by Vladimir Tsichevski about 3 years ago

  • % Done changed from 80 to 0

Greg Shah wrote:

Code Review Task Branch 3821c Revision 12130

It is good. I really only see coding standards issues.

...

Fixed in rev. 12135.

#22 Updated by Greg Shah about 3 years ago

It looks good.

Please add javadoc for AbstractDateTest.createDate(), TestDateFormat.beforeClass(), TestDateFormatParse.beforeClass(), TestDatetimeFormat.beforeClass().

Is this task done? Please set the % Done accordingly.

#23 Updated by Vladimir Tsichevski about 3 years ago

  • % Done changed from 0 to 100

Greg Shah wrote:

It looks good.

Please add javadoc for AbstractDateTest.createDate(), TestDateFormat.beforeClass(), TestDateFormatParse.beforeClass(), TestDatetimeFormat.beforeClass().

Is this task done? Please set the % Done accordingly.

Done in rev. 12138. I do not know if there is anything left to do in this very task.

#24 Updated by Greg Shah about 3 years ago

  • Status changed from Review to Closed

Also available in: Atom PDF