Your question deals with two aspects of method naming; semantics and formatting, so to speak (classifications that I have just come to think of).
Formatting
The issue of formatting is simple:
- something()
- faceAlgumaCoise()
- Facaalgumacoisa()
Formatting is agreed by the team and is easy to understand and maintain. I always propose that the team identify the culture of language and follow this culture. For example, in java the lowerCamelCase, other than C#, where the Uppercamelcase for method names, which is different from Ruby, where it is used Lower case with underline as a separator. But the final decision is the team and an automatic code analyzer can easily identify the code that is not following the convention.
What’s more important here about the formatting is that there is no convention for TDD. There is a convention for the team or for the project. All code must follow the convention, be it the production code or the test code.
Semantics
As we know, the name of a method must reveal its behavior, and must obey the business language (when it deals with business). And the signature of the method must ensure the abstraction of how the method works. The signature should reveal to the consumer everything he needs to know about the method without having to look at the code within it.
The unit test code has a different concept. The name of a
unit test method does not have to accurately reveal the
behaviour he expects, nor does he have to reveal the conditions,
entrances and exits ("when. .given.then")!
Although the name of the method has to be significant, it is his body, the code inside, that will describe the conditions, inputs and outputs expected.
Behold this example:
public class JogoVelhaTeste {
@Test
public void naoHaVencedor() {
String[] tabuleiro = {
"X", "O", null,
"O", "O", null,
"X", null, "X"} ;
JogoVelha jogoVelha = new JogoVelha();
assertNull(jogoVelha.obtemVencedor(tabuleiro));
}
}
When I want to know what determines whether there is no winner, the name of the method allows me to find it among the others, but to know in fact which input determines that there is no winner (in this case, a board with certain moves), and to know how is returned the information that there is no winner (in this case, the method obtainer returns null), I look at the code inside the method.
So the code itself within the method is the documentation of conditions, inputs and outputs. And it’s executable documentation! It will never be out of date, as with comments.
The article of Roy Osherove gives you some cool tips, but you don’t need a method called Sum_NumberIgnoredIfBiggerThan1000
. It would be better to call Sum_NumberIgnoredWhenTooBig
, which is probably significant enough. The entries, as I said, are described in the code itself within the method.
The test should not depend on comments
In this example, the author suggests a comment to describe the test. Ok, it’s not a simple comment; it’s . Net! But in the end it’s just a comment, which does not compile, which does not affect the operation of the test, and which may become outdated, and which will only be read as the developer’s last option when he is looking for an old code test (just as the developer can also read the code within the method).
Behold:
[TestMethod]
[Description("Given two tables And same data But different column order | When TableAssert | Then true")]
public void ColumnOrderDoesntMatter()
The name of this method is already quite significant. Dispense with the comment. The conditions, inputs and outputs can be checked in the body of the method itself, which the author of the example does not reveal but which well can be something like this:
[TestMethod]
public void ColumnOrderDoesntMatter() {
Table tableAscValues = new Table("value 1", "value 2");
Table tableDescValues = new Table("value 2", "value 1");
Assert.Equals(tableAscValues, tableDescValues);
}
Bring back the comment (Description) for the above method would be redundant.
Behavior Driven Development (BDD)
BDD is different from naming the method in style when. .given. then. BDD is about writing tests with this semantics using an executable language. So, as in my example (which is not BDD), it is the body of the test method that says the conditions, inputs and outputs, and not the name of the method.
Choosing a test method name using TDD
In TDD we write the test first. Often we still do not know how the solution design will be - it will emerge from the tests. Then it can be very difficult to immediately choose a good name for the test. No problem. Choose any name that reveals more or less the intention of what you want to test, then write some more tests, then revisit all the newly created methods and refactoring them, including improving their names.
Completion
The format of the test method name (Lower Camel case, underline...) must follow the same rules as the production code. These rules are agreed by the team.
The name of the test method should be significant, it should mainly describe the business behavior that is being tested; but the conditions, inputs and outputs are described by the code within the test. A testing method does not have the same type of abstraction that must have the methods of the business objects.
The body of the test method is the executable documentation of system behavior.
It seems that you already know several "patterns". The @Inert response outlines my personal form as well, in all the other ways I’ve used ( the ones you mentioned ) I found this more objective. Just an addendum, be consistent. If you choose a form, use it until the end, talk to your team and decide that with them. Don’t forget that TDD goes way beyond that, so be significant in the names, if you achieve this, the naming pattern will become just a supporting.
– BrenoSarkis