Hello! After a long time, I'm coming here to bring up another topic about unit testing. In this post, I will share with you a few techniques that I use to give effective names to my unit test methods.
I'm almost sure that most developers struggle somehow to name things, like classes, variables, functions and methods. Maybe because our creativity is not our strength, or we are tended to think logically or mathematically.
When I started writing unit tests, this issue was highlighted, and I caught myself spending more time figuring out a good name for my test than testing itself. This was because we have two main restrictions when naming the tests:
- Express the intent of the test
- Easy to read, straight to the point (in a Pull Request or a CI log)
That means we should avoid being too succinct and too expressive. We should find a midterm because the developer that is reading your tests doesn't want to be forced to read the test implementation due to a lack of description and also doesn't want to read a essay to be able to understand the intention of your test.
Finding this midterm is hard, so I will show you a few techniques that may help you.
Conventions and Patterns
Before figuring out better test names, I used to apply some patterns to my tests. All my test methods have the same formatting and some restrictions.
Having a pattern (or template) for naming benefits big teams. It helps the developer to understand others' code and to write new code faster. Let's see:
It isn't very pleasant having to scroll the code horizontally, especially when you are doing a code review or reading a CI log. Therefore, I strongly recommend you define a method name line length restriction.
Also, long test names indicate code smell. It means that the test may have a big setup or a very obscure condition to be executed, so it is a chance to re-evaluate the design of the subject under the test.
The number is up to you, but it should be long enough to fit on a GitHub page, so you don't have line breaks or horizontal scrolling. A good number is between 90 and 130 characters.
💡 The method name line lengths SHOULD be limited to a maximum of 130 characters.
You can enable the Xcode's page guide to see the characters limit on your editor.
To enable the Page guide, go to
Xcode > Preferences > Text Editing and check the Page guide column at.
After that, you will be able to see the page guide in your editor:
Should I write in lowercase? Uppercase? Camel-case? Snake-case? You decide. Just choose a format and apply it to your project.
In my case, I start the test with the
💡 The method name MUST start with
As a convention, I suggest you adopt a casing pattern for our method names. I'm used to writing in lower-camel case. E.g.:
// Doesn't have the defined underscore func testDeselectItemUponSecondTap()
// Snake case func test_deselect_item_upon_second_tap()
// Mixed cases func test_deselectItem_uponSecondTap()
💡 The method suffix MUST be in lower-camel case
After defining some conventions, we can proceed to the next step.
Expressible test summaries
The test name should contain a summary of what is being tested. This is the hardest part but imagine that you are writing a commit. So, when writing test summaries, try to complete the following sentence:
- "This test ensures that the sut …
… deselects an item upon a second tap."
… shows content on a successful response."
… returns the preferred payment method."
… completes with not found error on invalid URLs."
Simple as that. Just complete the sentence using Simple Present tenses.
Note that there is no information about spies, collaborators, class names, and implementation details, making the test uncoupled from details and more focused on the SUT behaviour/functionality. This makes the tests more flexible for refactoring.
Due to compliance with the line length restrictions, some article words can be omitted.
💡 The test summary SHOULD be written in Simple Present tenses
💡 The test summary SHOULD NOT leak implementation details
💡 The test summary SHOULD describe a sut behaviour
💡 Articles SHOULD be avoided
// Unecessary verbosity func test_givenASuccessfulResponseWhenTheScreenAppearShouldShowSomeContent()
// Past tense func test_returnedPreferedPayment()
// Too coupled with implementation details func test_completesWith404ErrorFromTheNetworkingForURLRequestsWithInvalidURLs()
These are some standards and techniques that I've been applying in my unit tests. It helps my team and me a lot, and I hope it helps you as well.
Of course, this post is very opinionated and based on my personal experience, so feel free to adapt it according to your context. Thanks for reading! See you!