[SalesForce] the best practice for initializing test data for multiple test methods

When you are writing multiple testMethods that ultimately start with the same test data, what is the best design for those initilization methods? By best design, I mean what are the implications for code coverage.

I see two possible designs but I cannot locate any references in documentation that indicate whether one is better or not.

Design 1:
In your test class, create a method that initializes all the necessary data and that each testMethod can call. This works fine, but my concern here is that the inclusion of a non-testMethod in the test class will interfere with Salesforce's Code Coverage calculations. And is this how test classes end up appearing in your listed of tested/covered Classes and Triggers in Dev Console?

Design 2:
Create a separate non-test class with data initialization methods that are called by your test methods in the test classes. This also works but the addition of extra classes is not ideal for controlling proliferation of Apex classes. The class is considered tested and averaged into Code Coverage but that's not necessarily desirable because it's truly just part of your testing infrastructure.

Best Answer

I second Lance's point that methods not marked as testMethod in a test class have no impact to Salesforce's calculation of code coverage. This means you can have as many methods as you want that aren't marked as testMethod.

To be clear, what excludes code from coverage calculations is the @isTest annotation, applied at the class level. testMethod simply tells Salesforce that a particular method should be executed as a test to provide code coverage and functional validation.

I also want to respond to your statement, "[Design 2] also works but the addition of extra classes is not ideal for controlling proliferation of Apex classes." In every org I've developed, I always create a TestOrganization class, whose sole purpose is to create test data for all Apex tests in that org. This class is annotated with @isTest and as a result has no impact on code coverage.

The way I use this class is conceptually the same as what your Design 1. Here's an example:

/*
 * Add a user to a single Chatter group. Make sure the user's group
 * membership appears when querying CollaborationGroupMember.
 */
@isTest
private static void testThatAddMemberCreatesCollaborationGroupMember() {

    // Create test data
    TestOrganization org = new TestOrganization();

    // Set parameters for the test
    User theUser = org.getUserByLastName('Xavier');
    CollaborationGroup theGroup =
        org.getCollaborationGroupByName('Test-Driven Development');

    ...
}