前置条件

这几天看Fresco和Glide的代码,发现他们都使用了Preconditions来做前置判断条件,发现这样写,代码变得既优雅又容易调试。 Preconditions的用法

OK,先看看平常写代码我们是怎么做的参数判断。
判断参数,如果参数配置错误,就抛出异常

int[] intArray = {1, 2, 3, 4, 5, 6};

private void testPreconditions(boolean preCondition, int[] array, int position) {
    if (!preCondition) {
        throw new IllegalArgumentException("preCondition not allow!!");
    }
    if (array == null) {
        throw new NullPointerException("array is null!!");
    }
    if (array.length == 0) {
        throw new IllegalArgumentException("array length is 0!!");
    }
    if (position > array.length || position < 0) {
        throw new ArrayIndexOutOfBoundsException("position error!!");
    }
    //do something...

}

这里看起来,没什么,但是如果我这个类很大,方法很多呢。看到全篇都是if(XX==null) throw{…}作何感想。
下面我们看看如果用Preconditions做前置判断

private void testPreconditions(boolean preCondition, int[] array, int position) 
{
    Preconditions.checkArgument(preCondition);
    Preconditions.checkNotNull(array);
    Preconditions.checkElementIndex(position, array.length, "position error!");
      //do something...
}

是不是清爽多了,使用Preconditions可以更清晰的表达程序意图。 为什么要使用Preconditions

那么你可能会问,为啥要用Preconditions,如果是空指针在用的时候,他自己就会抛出异常啊。
但是我们期望的是尽早抛出异常,而不是等到数据被层层传递,传递到非常深的位置,这样浪费系统资源更不利于我们开发精确定位错误。
所以推荐在方法的入口,或运算开始前,先检查数据。
例如:

   int length = datas.get(5).getDescription().concat("XX").split(",").length;

像这种代码,就算抛出空指针也不知道到底是那个对象空指针了,需要一步一步调试

这就是Preconditions另一个作用:尽早发现错误,精确控制出错的位置 抽取Preconditions
/**
* Created by lgq on 16-1-5.

 */
public class TestPreconditions {
 
    /**
     * 前置条件检查,当条件不满足时,就会抛出异常
     */
    @Test
    public void testPreconditions(){
        String constantName = null;
        //Preconditions.checkNotNull(constantName,"constantName 为 null");
 
        String str = "abc";
        Preconditions.checkNotNull(str,"str 为 null"); // 不会输出
 
        int age = 23;
        Integer number = 12;
        //Preconditions.checkArgument(age < 20, "age 必须要< 20");
        Preconditions.checkArgument(number < 20, "number 必须要< 20");
 
 
        List<Integer> integerList = Lists.newArrayList(3,5,6,98,2,45);
        for(int i=0; i<integerList.size(); i++) {
            // 检查数组下标是否越界
            int passIndex = Preconditions.checkElementIndex(i, integerList.size());
            //System.out.println("下标:"+ passIndex + " ==> 满足要求");
        }
 
        // 检查下标值7 是否在集合integerList中
        //Preconditions.checkElementIndex(7, integerList.size());
 
        //Preconditions.checkPositionIndex(8, integerList.size());
 
        Preconditions.checkPositionIndexes(2, 4, integerList.size());
 
        // 判断是否为true,当为false时,会抛出IllegalStateException
        Preconditions.checkState(4 < 3);
 
    }
 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
pytest是一个功能强大的Python测试框架,它提供了丰富的功能和灵活的配置选项来编写和运行测试。在pytest中,可以使用装饰器来定义测试用例的前置条件。 pytest的前置条件可以通过以下几种方式来实现: 1. 使用@pytest.fixture装饰器:可以使用@pytest.fixture装饰器定义一个前置条件函数,该函数可以在测试用例中被调用。前置条件函数可以返回一个值,供测试用例使用。例如: ```python import pytest @pytest.fixture def setup(): # 执行前置条件的操作 # 可以返回一个值供测试用例使用 return "precondition" def test_example(setup): # 使用前置条件的返回值 assert setup == "precondition" ``` 2. 使用@pytest.fixture(scope="module")装饰器:可以使用scope参数来指定前置条件的作用域。默认情况下,前置条件的作用域是函数级别的,即每个测试用例都会执行一次前置条件。如果将scope参数设置为"module",则前置条件只会在模块级别执行一次。例如: ```python import pytest @pytest.fixture(scope="module") def setup(): # 执行模块级别的前置条件操作 return "precondition" def test_example(setup): assert setup == "precondition" ``` 3. 使用autouse参数:可以在@pytest.fixture装饰器中使用autouse参数,将前置条件应用于所有测试用例,而无需在测试用例中显式调用。例如: ```python import pytest @pytest.fixture(autouse=True) def setup(): # 执行前置条件的操作 return "precondition" def test_example(): # 不需要显式调用前置条件 assert setup == "precondition" ``` 这些是pytest中定义前置条件的几种方式。通过使用这些装饰器,可以方便地在测试用例中使用前置条件,并且可以根据需要灵活地控制前置条件的作用范围。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值