Releases: sbabcoc/JUnit-Foundation
Upgrade dependencies
Upgrade to the latest releases of Java-Utils (2.2.0), Settings (2.3.11), and Logback (1.2.9).
For map keys, use Method.toString() instead of Method.hashCode()
It turns out that the hashCode() implementation of the java.lang.reflect.Method class is really weak. It only incorporates the declaring class and the method name, omitting other features of Method objects that make them unique. The implementation uses a non-standard process and isn't a match for the equals() method of this class. Because the hashcode is so weak, it shouldn't be used as a Map key, but there were several places in JUnit Foundation where it was used for just this purpose.
In this release, I replaced uses of java.lang.reflect.Method#hashCode() (both explicit and implicit) with the toString() method.
Replace more reflection with byte code transformations
In this release, I've replaced more instances of reflection-based field access with equivalent methods added via byte code transformations. I'm approaching a point where the remaining instances are either targeting transient unnamed objects or couldn't be replaced because of type load order.
This work included relocating and optimizing the implementation of the ParameterizedDescription fix for the JUnitParams runner. With a lot less code and simpler implementation, this new strategy produces the same result much more efficiently.
Replace reflective operations with Byte Buddy transformations
In this release, I eliminated reflective access to private fields that were throwing access violation warnings. These were definite compatibility problems for newer JVM releases.
In addition to making JUnit Foundation compatible with Java 17+, this release also fixes some fundamental errors with the annotation proxies produced for timeout management and automatic retry related to final fields and annotation type reporting.
Finally, I extracted the class transformation code from LifecycleHooks into a new JUnitAgent class, eliminating the type restrictions the presence of this code imposed on this core interface. In a future release, I may use this new factoring to improve the type safety of this core utility class.
Add exception to retry notifications; fix assertions
In this release, I updated the retry notification message to add the stack trace of the exception that caused the test to fail. The addition of this exception information is requested via the RETRY_MORE_INFO setting or by setting the logging level to DEBUG.
Upgrade Settings to version 2.3.10
In this release, I upgraded Settings to the latest release (version 2.3.10)
Upgrade Java-Utils to version 2.1.0
In this release, I upgraded Java-Utils to the latest release (version 2.1.0)
Tweak dependencies to suppress aggressive Guava warning
Guava 30.1.1-android adds an obtrusive warning regarding the intent to remove support for Java 7 in an unspecified future release. I figured out a way to suppress the warning, but this requires pulling in guava transitively through guava-agent. Adding to the opacity, guava-agent is pulled in transitively through java-utils:
com.nordstrom.tools:java-utils:2.0.3
└── com.nordstrom.tools:guava-agent:30.1.1a
└── com.google.guava:guava:30.1.1-android
Upgrade dependencies and plugins, update README
This release contains no functional changes but is instead focused on project housekeeping.
In addition to project file changes, I also updated the README file:
- Add information about new functions and features.
- Revise code examples to match changes in the underlying API.
- Add notes to clarify the usage of
getCallableOf(Description)andencloseCallable(Method, Object, Object...)methods. - Add note regarding "atomic test" objects supplied with suite-level failures.
- Document new method used to identify retried tests, which handles both @Test and @Theory methods.
Add verification that framework object references have been released
This release is a follow-up to previous work that added management of stored references to JUnit framework objects. The unit test collection now verifies that these references are released within the scope where they should be. To maintain the encapsulation of the underlying collections, the test implementation accesses these collections via Java reflection. This necessarily results in tight coupling between the API implementation and the corresponding tests, which is perhaps a good thing in this context.
- I revised the behavior of
AtomicTest.isTest()to check the attached annotations, instead of relying on theisTest()method of the wrapped Description object. The documentation for the latter states that this method indicates whether the represented method is an "atomic test", but in actuality only indicates that the described framework object has no children. - I dug deeper into the weird world of JUnitParams, implementing a more comprehensive augmentation of the incomplete Description objects it creates.
- I added code to recover from the
NullPointerExceptionthrown from within the guts of JUnitParams if you ask it to describe a configuration method (@BeforeClass, @Before, @After, or @AfterClass). - I expanded the scope that will be searched for attached run listeners, enabling clients to access listeners that are attached directly to the run notifier.
- I also resolved the warnings that were reported by the Sonatype Lift static analysis tool.