Test Naming Convention
Tags: coffeelessthoughts, todayilearned, testing
Published: 2022-07-28 18:51:00

> There are only two hard things in Computer Science: cache invalidation and naming things. –Phil Karlton

There may be nothing as subjective as a good name. Luckily we're naming tests, not children, so we'll get by.

___
## The Class Name

There are 2 parts to a test name: the <u>class name</u> and the <u>method name</u>. It's important to remember the significance of the former.

The **class name** should provide clarity to the logical grouping of tests it contains. Some examples:
- `UsersApiTests`
- `FileUploadTests`
- `UserContractValidationTests`

___
## The Method Name
I've adapted 2 useful formats for the method name: the happy path, and the edge case.

These conventions are used _above the unit test level_ in the testing pyramid, e.g. component, integration, e2e tests.

We'll cover unit test naming towards the end.

___
### Format: Happy Path

A happy path test makes sure the functionality works as expected when given <u>straightforward inputs</u>.

> &emsp;**\<Functionality>\_VERIFY\_\<Result>**

Note: Writing connectors, e.g. "verify", in all CAPS allows us to visually parse the components more easily.

#### Composition

&emsp;**\<Functionality>**
&emsp;&emsp;: The general functionality to be tested; more granular than the class name, adds clarity

&emsp;**\<Result>**
&emsp;&emsp;: The expected test outcome or behavior, e.g. return value, response code, state change, action taken

#### Examples
- `FileUploadTests.DeviceUpload_VERIFY_PdfUploadToKindleSuccess`
- `FileUploadTests.DeviceUpload_VERIFY_TxtUploadToKindleFails`
- `FileUploadTests.CloudUpload_VERIFY_EpubUploadSuccess`
- `UsersApiTests.UsersPost_VERIFY_Response201Created`

___
### Format: Edge Case

An edge case test makes sure the functionality is working as expected when the <u>inputs are not ideal</u>, e.g. out of bounds, on the fringe, or otherwise.

> &emsp;**\<Functionality>\_WHEN\_\<Condition>\_THEN\_\<Result>**


Note: Including "when" and "then" clarifies the method name components for programmers and non-programmers alike.


### Composition

&emsp;**\<Condition>**
&emsp;&emsp;: The condition, state, or branch of logic to be isolated

#### Examples
- `FileUploadTests.CloudUpload_WHEN_UserNotPremiumMember_THEN_PDFUploadFails`
- `UsersApiTests.UsersPost_WHEN_InvalidRequestParams_THEN_Response400BadRequest`
- `UsersApiTests.UsersPost_WHEN_NameLengthBelowMin_THEN_Response400BadRequest`

___
It's a good idea for the scope of a test name to reflect the target code's level of abstraction. Compare these to the above `UserApiTests`.

- `UserCreationTests.ValidateContract_VERIFY_UserContractValidationSuccess`
- `UserCreationTests.ValidateContract_WHEN_EmailFormatNotValid_THEN_ReturnFalse`
- `UserCreationTests.ValidateContract_WHEN_PasswordHasNoSpecialChar_THEN_ThrowIllegalArgumentException`
- `UserCreationTests.ValidateContract_WHEN_NameLengthExceedsMax_THEN_ThrowIllegalArgumentException`

Lastly, well-written edge case tests are a succinct representation of the conditions which are important for the happy path of that functionality.

___
### Test Type: Unit

Aren't these conventions a little overkill for unit tests? Maybe so. I tend to use a simpler variant for low-level tests.

> &emsp;**\<Method?>\_\<InputOrType>\_\<Output|PoD>**


### Composition

&emsp;**\<Method?>** (Optional)
&emsp;&emsp;: The purpose of the method being tested; it does NOT need to match the method name; not required if the test class name is clear about the target code

&emsp;**\<InputOrType>**
&emsp;&emsp;: Either the value of the input parameter OR type of input depending on input complexity

&emsp;**\<Output|PoD>**
&emsp;&emsp;: Either the expected output OR the point of difference (PoD) as compared to the happy path, i.e. what makes this edge case relevant

#### Examples
- `RomanNumeralTests.RomanToInt_MMCDLXVIII_2468`
- `RomanNumeralTests.IntToRoman_1994_MCMXCIV`
- `ReverseIntegerTests.Positive_Overflow`
- `ReverseIntegerTests.Negative_DoubleOverflow`

___
### Quiz

**Q:** Which one is better?
1. `DeviceUpload_VERIFY_TxtUploadToKindleFails`
1. `DeviceUpload_WHEN_TxtFile_THEN_UploadToKindleFails`

**A:** Both are perfectly acceptable.
1. The happy path format is more concise and just as clear.
2. The edge case format is self-documenting; it tells us the file type is important to the happy path for device file upload.

There's a trade-off as with most things in CS and in life. The decision is up to you!

___
### Final Thoughts

Remember that there's no silver bullet, nor do we need one. We have the power to use the right tool for the right job.

&nbsp;

Until Next Time,
Ryo
___
TL;DR - Prefer verbose clarity over terse obscurity.

___
### References:
1. [GivenWhenThen | Martin Fowler](https://martinfowler.com/bliki/GivenWhenThen.html)
1. [Unit test naming best practices | StackOverflow](https://stackoverflow.com/questions/155436/unit-test-naming-best-practices)
1. [7 Popular Unit Test Naming Conventions | VitalFlux](https://vitalflux.com/7-popular-unit-test-naming-conventions/)
1. [Unit Test Naming Convention | Matheus.ro](https://matheus.ro/2017/09/24/unit-test-naming-convention/)
1. [You are naming your tests wrong! | Enterprise Craftsmanship](https://enterprisecraftsmanship.com/posts/you-naming-tests-wrong/)

### Further Reading:
1. [Picking better names for variables, functions, and projects | Mac Wright](https://macwright.com/2021/02/17/the-naming-of-things.html)
1. [Practical Test Pyramid | Martin Fowler](https://martinfowler.com/articles/practical-test-pyramid.html)
1. [Unit tests value proposition | Enterprise Craftsmanship](https://enterprisecraftsmanship.com/posts/unit-test-value-proposition/)
1. [Software Testing Guide | MartinFowler](https://martinfowler.com/testing/)