The title says it all. I've recently inherited an application that is written by different people at different times and looking for guidance on how to standardize.
I ran across two good suggestions. Links here: http://slott-softwarearchitect.blogspot.com/2009/10/unit-test-naming.html
http://weblogs.asp.net/rosherove/archive/2005/04/03/TestNamingStandards.aspx
In that situation I'd probably find the naming convention that was used the most and refactor the rest of the code to use that. If the one that was used the most is truly horrid, I'd still look to the existing code and try to find one that I could live with. Consistency is more important than arbitrary conventions.
I use a FunctionTestCondition
construct. If I have two methods, Get
and Set
I would maybe create the following test methods:
GetTest
being a positive test (everything is ok).GetTestInvalidIndex
to test an invalid index being passed to the method.GetTestNotInitialized
to test when the data is not inited before use.SetTest
SetTestInvalidIndex
SetTestTooLargeValue
SetTestTooLongString
It's instructive to look at BDD (behavioural driven development) and this blog post in particular.
BDD is essentially focusing on components and what they should do. Consequently it impacts directly on how you name/structure your tests, and the code they use to set up conditions and validate. BDD allows not only the developers to read/write the tests, but non-technical members of the team (business analysts etc.) can contribute by specifying the tests and validating them.
I just write what it's for. It's not like you're going to have to type the names in anywhere else, so having a testWibbleDoesNotThrowAnExceptionIfPassedAFrobulator
isn't a problem. Anything which is a test begins with 'test', obviously.
Group your tests by setup, make a test class around this setup and name is with suffix Test or IntegrationTest. Using a test framework like JUnit or TestNG you can name your test methods as you want. I would name the method as what it tests, a sentence in camel case, not test prefix. The frameworks use a @Test
annotation to mark a method as test.
Assuming NUnit:
[Test]
public void ObjectUnderTest_StateChanged_Consequence()
{
Assert.That(tra_la_la);
}
[Test]
public void ObjectUnderTest_Behaviour_Consequence()
{
Assert.That(tra_la_la);
}
for example:
[Test]
public void WifeIsTired_TakeWifeToDinner_WifeIsGrateful()
{
Assert.That(tra_la_la);
}
[Test]
public void WifeIsTired_MentionNewGirlfriend_WifeGetsHalf()
{
Assert.That(tra_la_la);
}
There is no standard as such, different people/places will have different schemes. The important thing is you stick to a standard.
Personally I'm a fan of the following - example code in C#, but very close to Java, same rules apply:
[Test]
public void person_should_say_hello()
{
// Arrange
var person = new Person();
// Act
string result = person.SayHello();
// Assert
Assert(..., "The person did not say hello correctly!");
}
Explicit
The test name should give the name of the class under test. In this example, the class being tested is Person
. The test name should also have the name of the method that is being tested. This way, if the test was to fail, you'll at least know where to look to solve it. I'd also recommend following the AAA - Arrange, Act, Assert rule, it will ensures your tests are easy to read and follow.
Friendly fail messages
When it comes to asserting a result/state, its useful to include an optional message. This makes it easier when a test fails, especially when run as part of a build process or via an external tool.
Underscores
The final (though optional) stance I follow is using underscores for tests names. While I'm no fan of underscores in production code, their use in test names is useful as test names are often much longer. Quickly glancing at a test name that uses underscores proves to be much more readable, though this is subjective and the source of much debate with regards unit testing practices.
Integration Tests
The same standards apply to integration tests, the only difference being the location of such tests should be separate from unit tests. In the example code above, the test class would be called PersonTests
and located in a file called PersonTests.cs
. The integration tests would be named in a similar manner - PersonIntegrationTests
, located in PersonIntegrationTests.cs
. The same project can be used for these tests, but ensure they are located in separate directories.