Apex 测试类

1. 测试类

a. 为啥要写烦人的测试类

  1. 当SandBox 部署Code到正式环境时,SF强制要强(>=75%,平台要求)。
  2. 对功能模块检测(单元测试不保证程序做正确的事,但能帮助保证程序正确地做事)。
  3. 反馈速度快,一旦在执行测试类时,通过断言,出现预期结果与实际结果不符合时,就发现问题,比从测试人员反馈即时。
  4. 后期如果对程序修改,比如新加字段,修改字段类型,执行测试类时,可以发现新加的内容是否对原有逻辑造成影响。
  5. 文档作用。(因为测试类根据场景来做的,通过大致阅读测试类,不用看原有代码,可以大概知道对应的功能,前提是测试比效规范和有意义的说明)
  6. 对功能设计的反馈。(如果一个功能很难写出对应的测试类,则该功能的设计存在不良的缺陷)

b. 写测试类面临的问题

  1. 项目时间问题(认为测试类不重要,所以并没有预留出足够的时间用来书写测试类,导致开发人员抱着能部署的心态书写测试类,把目标定在75%这个点上)
  2. 开发人员不重视测试类,以完成功能开发为目地,而不是写出符合要求,且健状的程序来要求自己。

c. SF测试类

  1. 测试类中可直接访问的对象有如下 User,Profile,Organization,AsyncApexJob,CronTrigger,RecordType,ApexClass,ApexTrigger, ApexComponent,ApexPage
  2. 使用IsTest(SeeAllData=true) 可以直接访问系统中的记录
  3. 测试数据与系统数据隔离
  4. 测试类中无法创建字段历史,因为测试数据不会提交(之前遇到过更新记录后,查询历史,发现历史为空)
  5. 为了避免对一个对象的创建在每个测试类中书写,可以创建一个类,专门来创建每个对象,类似于这样。
 // @Author 在山的那边
//  @Date 2016年8月29日
//  @Description
// 为测试类提供对象
@isTest
public class TestData {
    public static Account getAccount(Id recordTypeId){
      Account entity = new Account();
      entity.Name = 'TestAccount';
      entity.RecordTypeId = recordTypeId;
      return entity;
    }
    public static Account getAccount(String nameIndex){
      Account entity = new Account();
      entity.Name = 'TestAccount'+nameIndex;
      return entity;
    }
    public static Contact getContact(Id accountId,String nameIndex){
      Contact con = new Contact();
      con.LastName = 'TestContact'+nameIndex;
      con.AccountId = accountId;
      return con;
    }
}

6 . 需要测试的代码

//@Author 在山的那边
 //@Date 2016年8月29日
 //@Description
 // 一个小例子
 //@Test {UnitClass:[
 //        testAccountAction_getAccount(),
 //        testAccountAction_getContact()
 //      ]}
 //@See {}
 //@Schedule{}
 //@Modify[
 // {时间:2016年8月29日 00:18,修改人:在山的那边 ,描述:init}
 //]
 //
public class AccountAction {
  @TestVisible private Account account;

  public void getAccount(){
    this.account = [SELECT Id,Name FROM Account][0];
  }

  public List<Contact> getContact(){
    List<Contact> conList = [SELECT Id,Name FROM Contact WHERE AccountId =:account.Id];
    return conList;
  }

}

7 . 创建测试类 SF创建测试类很简单,在类前加上annotation @isTest 或者 在使用关键字 testMethod 和 static 修饰方法(如下形式),个人偏向于测试方法写在一个测试类中,当测试类较多时,另起一个测试文件,而不是一个class写一个测试类文件

public class myClass {
    static testMethod void myTest() {
       // Add test method logic using System.assert(), System.assertEquals()
       // and System.assertNotEquals() here.
     }
}
@isTest
private class MyTest {
   // Methods for testing
}
@isTest
public class UnitClass {

  @testSetup static void methodName() {
    Account acc01 = TestData.getAccount('01');
    Insert acc01;

    Contact con01 = TestData.getContact(acc01.Id, '01');
    Insert con01;
  }

//个习惯测试类的命名格式为:test+类名+"_"+方法名,在注释中同样写清楚测试类怀测试方法
//
 // @ApexClass  testAccountAction
 //@ApexMethod getAccount
 // @Description
 // @Author 在山的那边
 // @Date 2016年8月29日
  @isTest static void testAccountAction_getAccount() {
    AccountAction accAction = new AccountAction();
    accAction.getAccount();
    System.assertEquals('TestAccount01', accAction.account.Name);
  }

 // @ApexClass  testAccountAction
 // @ApexMethod getContact
 // @Description
 // @Author 在山的那边
 // @Date 2016年8月29日
  @isTest static void testAccountAction_getContact(){
    AccountAction accAction = new AccountAction();
    accAction.getAccount();
    List<Contact> conList   =  accAction.getContact();
    System.assertEquals('TestContact01', conList.get(0).Name);
  }
}
代码中的注释为多行 ,排版问题改为//
在sublime中通过shift + 双击可以导航到定义处,这就是为什么在注释中写明测试类与测试的方法
这样在程序中可以点击导航对应的测试方法,在测试方法中能快速导航到程序中

8 . 在控制台执行对应的测试类。

输入图片说明

9 . @TestVisible 作用是访问类的私有变量,如一些内部类或者私有变量需要访问或者给值时

10 . @testSetup 在执行测试方法前执行,类似于junit中的@before 可以执行一些公共数据的新建等工作,但是一但该方法有错误,则整个测试类全部失败,建议只有一个testsetup方法

11 . 通过System.assertEquals or System.assert() or System.assertNotEquals() 来验证预期结果与实际结果 比较,一旦不成立,则测试类提示失败,日志中会体现预期值为多少,实际为多少。 输入图片说明

12 . runAs 模拟不同用户操作

13 . startTest 和 stopTest 在这两个方法中间执行一些耗时操作,在stoptest 后再使用断言判断,如job,如果不在方法中间,则断言取不到值,原因是当执行判断时,job也许还没有执行完成。同时还能避免一些limit问题,webservice,remote acton 操作时都需要写在中间。该测试方法中只能调用一次。

14 . 测试方法中不要出现硬码,否则出现在Sandbox中正常,到正式中就出错,少依赖基础数据。

15 . Trigger 覆盖率必须>0

16 . try…catch 捕获代码中出现的异常,如trigger中 字段.adderror 等形为

以上仅参考,如果错误欢请指出,参考内容为SF的apex 指南, SF也建议不要将目光仅放在75%上,要尽量达到95%以上,最后需要通过断言判断程序是否与期望相同 SFDC测试类的最佳实践link

转载于:https://my.oschina.net/SpringZhang/blog/739064

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值