Unit Tests

http://wiki.developerforce.com/page/An_Introduction_to_Apex_Code_Test_Methods

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content%2Fapex_testing.htm

Apex Unit Tests
The test method exercises and validates the code in the trigger and class to test and verify code coverage.
This class is defined using the @isTest annotation
Testing is an important part of the development process. Before you can deploy Apex or package it for the Force.com AppExchange, the following must be true.
 Unit test methods take no arguments, commit no data to the database, and are flagged with the testMethod keyword in the method definition.
You must have 75% test coverage to be able to deploy your Apex code to your production organization.

@IsTest
public/private class <Test Class Name>{
static testMethod void <Test Method Name>() {

<Test Method Body : write all the case to fire the class or trigger to be tested>

}
}
Note the following.
    • When deploying to a production organization, every unit test in your organization namespace is executed.
    • Calls to System.debug are not counted as part of Apex code coverage.
    • Test methods and test classes are not counted as part of Apex code coverage.
    • While only 75% of your Apex code must be covered by tests, your focus shouldn't be on the percentage of code that is covered. Instead, you should make sure that every use case of your application is covered, including positive and negative cases, as well as bulk and single records. This should lead to 75% or more of your code being covered by unit tests.
  • Every trigger must have some test coverage.
  • All classes and triggers must compile successfully.
Test data created in the test method is automatically rolled back when the execution completes, and you don’t need to delete any test data explicitly.


Defining a Test Method using the testMethod keyword

To define an Apex method as a 'test method', simply define the method as static and add the keyword testMethod. A test method can be defined in any Apex class. A test method can not be defined in an Apex trigger. (Note: Testmethods cannot be called outside of a test context.) Here's a simple example:
1public class myClass {
2    static testMethod void myTest() {
3       // Add test method logic using System.assert(), System.assertEquals()
4       // and System.assertNotEquals() here.
5     }
6}

Defining classes of test methods with the isTest annotation

Use the isTest class annotation to define classes that only contain code used for testing your application. If your test methods are contained within their own classes and the Apex class only contains test methods, it is ideal to use the isTest annotation.
Classes defined with the isTest annotation do not count against your organization limit of 2 MB for all Apex code. Classes annotated with isTest can be declared as private or pubic. They cannot be interfaces or enums either.
Here is an example of the syntax:
1@isTest
2private class MyTest {
3   // Methods for testing
4}

Test.startTest/Test.stopTest

There are two additional system static methods provided by Apex. These methods, Test.startTest and Test.stopTest, are used when testing governor limits. Or in other words, executing test scenarios with a larger data set.
The Test.startTest method marks the point in your test code when your test actually begins. Each test method is allowed to call this method only once. All of the code before this method should be used to initialize variables, populate data structures, and so on, allowing you to set up everything you need in order to run your test. After you call this method, you get a fresh set of governor limits for the remainder of the test until you call Test.stopTest.
The Test.stopTest method marks the point in your test code when your test ends. Use this method in conjunction with thestartTest method. Each test method is allowed to call this method only once. After calling this method, any post assertions are done in the original context.
These static methods allow a test method to separate the Apex resources and governor limits being used to prepare and initialize the dataset from the resources and limits used during the actual test execution.
Here is a sample test method function that uses these methods:
01static testMethod void verifyAccountDescriptionsWhereOverwritten(){
02    // Perform our data preparation.
03    List<Account> accounts = new List<Account>{};
04         
05    for(Integer i = 0; i 200; i++){
06        Account a = new Account(Name = 'Test Account ' + i);
07        accounts.add(a);
08    }
09
10    // Start the test, this changes governor limit context to
11    // that of trigger rather than test.
12    test.startTest();
13         
14    // Insert the Account records that cause the trigger to execute.
15    insert accounts;
16         
17    // Stop the test, this changes limit context back to test from trigger.
18    test.stopTest();
19         
20    // Query the database for the newly inserted records.
21    List<Account> insertedAccounts = [SELECT Name, Description
22                                      FROM Account
23                                      WHERE Id IN :accounts];
24         
25    // Assert that the Description fields contains the proper value now.
26    for(Account a : insertedAccounts){
27      System.assertEquals(
28        'This Account is probably left over from testing. It should probably be deleted.',
29        a.Description);
30    }
31}
1trigger OverwriteTestAccountDescriptions on Account (before insert) {
2  for(Account a: Trigger.new){
3    if (a.Name.toLowerCase().contains('test')){
4      a.Description =
5        'This Account is probably left over from testing. It should probably be deleted.';
6    }
7    }
8}
The example above helps illustrate how to separate the test data preparation from the actual test scenario. The first step of the example creates 200 Accounts that are required for the test scenario-and inserting these 200 Account records will have them applied to the governor limits. So in order to separate the Apex resources and governor limits used during test data preparation from the actual test scenario, the example uses the Test.startTest() and Test.stopTest() methods. Therefore, the Apex code executing within the startTest and stopTest methods will obtain their own Apex governor limits and resources. If the test method did not usestartTest() and stopTest(), the test scenario might have hit a governor limit since some of the available Apex resources (such as total number of records processed by a DML statement) were used up by data preparation steps.

System.runAs()

Generally, all Apex code runs in system mode, and the permissions and record sharing of the current user are not taken into account. The system method, System.runAs(), lets you write test methods that change user contexts to either an existing user or a new user. All of that user's record sharing is then enforced. You can only use runAs in a test method. The original system context is started again after all runAs() test methods complete.
Please note that the runAs() functionality will test and verify proper data sharing and data access. But runAs() does not validate CRUD or Field Level Security permissions.
01public class TestRunAs {
02   public static testMethod void testRunAs() {
03      // Setup test data
04      // This code runs as the system user
05
06         Profile p = [select id from profile where name='Standard User'];
07         User u = new User(alias = 'standt', email='standarduser@testorg.com',
08            emailencodingkey='UTF-8', lastname='Testing', languagelocalekey='en_US',
09            localesidkey='en_US', profileid = p.Id,
10            timezonesidkey='America/Los_Angeles', username='standarduser@testorg.com');
11
12
13         System.runAs(u) {
14           // The following code runs as user 'u'
15           System.debug('Current User: ' + UserInfo.getUserName());
16           System.debug('Current Profile: ' + UserInfo.getProfileId()); }
17           // Run some code that checks record sharing
18        }
19}
The above test method creates a new user (with a profile of a standard user), and executes a block of code in the context of this new user.

Comments

Popular Posts