views:

134

answers:

8

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.

+1  A: 

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.

Bill the Lizard
Its not an arbitrary convention I'm after, but a best practice.
HDave
+1  A: 

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
Anders Abel
+2  A: 

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.

Brian Agnew
Very interesting link -- thanks.
HDave
+4  A: 

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.

Pete Kirkham
A: 

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.

Arne Burmeister
+1  A: 

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);
}
Duncan
An alternative to this is MethodUnderTest_Scenario_Expectation. For example AddItem_EmptyCart_OneItemInCart(). This assumes one test fixture class per class under test.
Ryan
@Ryan -- Your suggestion is what I ended up using. It's also the recommendation of the book "the art of unit testing".
HDave
+1  A: 

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.

Finglas