consistent naming for tests

John Hendrikx john.hendrikx at gmail.com
Tue Jul 9 11:52:35 UTC 2024


On 09/07/2024 11:33, Johan Vos wrote:
> Hi,
>
> An interesting question from John Hendrikx 
> (https://github.com/openjdk/jfx/pull/1283/#discussion_r1637684395) 
> probably needs some general discussion on this list.
> Afaik, we don't have guidelines for how to name tests (in 
> https://github.com/openjdk/jfx/blob/master/CONTRIBUTING.md#coding-style-and-testing-guidelines)
>
> In the different test files we have, I see different patterns:
> * in some cases, tests are always prefixed with `test` (e.g. `testFoo()`)
> * in some cases, tests have a concise but somehow meaningful name 
> (e.g. `testScrollBarStaysVisible`)
> * in some cases, tests refer to JBS issues (e.g. testJDK8309935)
> * in some cases, the test is explained in comments.
>
> I think it would be good to have some consistency going forward. (I'm 
> not advocating we need to rename existing tests!)
> I don't have a strong preference myself, but I think the link to the 
> JBS issue that triggered the creation of a specific test is always 
> good to have. I am also very ok with comments, but I learned not 
> everyone likes that.

Hi Johan,

I didn't like the test name primarily because it has an indirection in 
it -- to know what it is supposed to do, I need to go to another system, 
log in, and read the issue.  The issue often however also won't really 
have just one problem or just a tiny description.  So although I think 
it is fine to refer to an issue number, I think the test itself would 
still benefit of a reminder what it is testing (and I see you added a 
comment now, so that helps).

Same goes for comments in the code; I often just see code lines marked 
with "RT-xyz" or "JDK-xyz" -- sometimes referring a non-public issue.  
Just a small description in the code what the problem was is way more 
helpful to (future) maintainers, like ourselves, then a random number 
without further explanation.

As for test naming, it will depend a bit on what you're testing. 
Sometimes using a nested class pattern like this is good:

     class ListTest {
         @Nested
         class WhenEmpty {
               void thenIsEmptyShouldReturnTrue() {
                    assertThat(list.isEmpty()).isTrue();
               }
               void thenSizeShouldBe0() {
                    assertThat(list.size()).isEqualTo(0);
               }
               void thenGettingFirstElementShouldThrowException() {
                    assertThatThrownBy(() -> list.get(0))
.isInstanceOf(IndexOutOfBoundsException.class)
                         .hasMessage("index 0");
               }

               @Nested
               class AndFiveElementsAreAdded {
                     // add 5 elements in beforeEach

                     void thenIsEmptyShouldReturnFalse() {}
                     // etc
               }
         }

         // or if nesting becomes too crazy, start from base again:
         @Nested
         class WhenContainingFiveElements {
               void thenIterationShouldReturnThoseFiveElements() {
                     assertThat(list).containsExactly(List.of("A", "B", 
"C", "D", "E"));
               }
               // etc.
         }
     }

The above pattern has top level nested classes start with "When" 
followed by a given state, nested classes start with "And" and a 
modification of the state, and test method naming follows the pattern 
"then <action> should <result>".  When combined with a 
DisplayNameGenerator that transforms camel case names to spaced names, 
the tests form more or less normal English sentences.

(Note: I used AssertJ here for much more fluently readable asserts)

That said, I wouldn't go for a fixed naming pattern for test methods as 
it can be a bit situational, but I do think they should be descriptive.

--John

>
> Thoughts?
>
> - Johan


More information about the openjfx-dev mailing list