Description
API(s)
com.google.common.collect.testing.*
For example MapTestSuiteBuilder
or ListTestSuiteBuilder
How do you want it to be improved?
The collection test suites should make it easier to identify where in the user code the test suite was created / to which user test class it belongs, especially if an assertion fails in the test suite
Why do we need it to be improved?
There are two issues with the collection test suites:
- You have to specify a test suite name with
named(String)
, however if you specify- a custom short name, then depending on where you run the test, you don't immediately understand which user class created the test suite
(this differs between tooling / IDEs; in Eclipse there seems to be no indication which of the user's test classes created the test suite, in IntelliJ and Maven on console it does include the test class name in the UI / console output) - the name of the enclosing test class, then the test output becomes verbose because Guava seems to repeat the name for its nested tests, e.g. " [collection size: one]"
- a custom short name, then depending on where you run the test, you don't immediately understand which user class created the test suite
- if an assertion fails, the complete stack trace is only Guava code
Example
Take for example this Maven test failure from Gson:
[INFO] Running com.google.gson.JsonArrayAsListSuiteTest
Error: Tests run: 404, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.445 s <<< FAILURE! -- in com.google.gson.JsonArrayAsListSuiteTest
Error: com.google.common.collect.testing.testers.CollectionCreationTester.testCreateWithNull_unsupported[JsonArray#asList [collection size: one]] -- Time elapsed: 0.001 s <<< FAILURE!
java.lang.AssertionError: expected to throw NullPointerException
at com.google.common.collect.testing.testers.ReflectionFreeAssertThrows.doAssertThrows(ReflectionFreeAssertThrows.java:101)
at com.google.common.collect.testing.testers.ReflectionFreeAssertThrows.assertThrows(ReflectionFreeAssertThrows.java:61)
at com.google.common.collect.testing.testers.CollectionCreationTester.testCreateWithNull_unsupported(CollectionCreationTester.java:58)
at jdk.internal.reflect.GeneratedMethodAccessor96.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at junit.framework.TestCase.runTest(TestCase.java:177)
at junit.framework.TestCase.runBare(TestCase.java:142)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:130)
at junit.framework.TestSuite.runTest(TestSuite.java:241)
at junit.framework.TestSuite.run(TestSuite.java:236)
at junit.framework.TestSuite.runTest(TestSuite.java:241)
at junit.framework.TestSuite.run(TestSuite.java:236)
at junit.framework.TestSuite.runTest(TestSuite.java:241)
at junit.framework.TestSuite.run(TestSuite.java:236)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:316)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:240)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:214)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:155)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
Or generally how the test suites are used in Gson:
Current Behavior
Luckily Maven includes the name of the test Java class it is executing (in the example JsonArrayAsListSuiteTest
), but besides that:
- The test name is (mostly) a Guava defined test name:
com.google.common.collect.testing.testers.CollectionCreationTester.testCreateWithNull_unsupported
- The complete stack trace is either Guava or JUnit, there is not a single mention of the Gson test class which created the test suite
You would have to notice the test suite name (in the example "JsonArray#asList") and then manually look for the user test class which creates a test suite with that name.
Desired Behavior
See "How do you want it to be improved?" above
Not completely sure how it could be improved; some ideas:
- Guava could get the caller of
createTestSuite()
and include its qualified class name in the test suite name (maybe?)
That might be mostly relevant for Eclipse, see "Why do we need it to be improved?" above. Alternatively the user could do that themselves by creating an additionalTestSuite
with that qualified class name, wrapping the Guava test suite. - Guava could get the caller of
createTestSuite()
and include it in the stack trace of assertion errors (possibly as dummy 'suppressed' or 'cause' exception) - Guava could get the class name of the used
TestContainerGenerator
implementation and somehow include it in the test suite names or assertion errors (?)
These ideas are not ideal; any other ideas are welcome!
Concrete Use Cases
See "Example" section above
Checklist
-
I agree to follow the code of conduct.
-
I have read and understood the contribution guidelines.
-
I have read and understood Guava's philosophy, and I strongly believe that this proposal aligns with it.