菜鸟笔记
提升您的技术认知

java之单元测试与注解与枚举-ag真人游戏

软件测试

目的:在规定的条件下,对程序进行操作,以发现程序错误,衡量软件质量,并对其是否满足设计要求进行评估的过程

测试分类

黑盒测试:软件的黑盒测试意味着测试要在软件的接口处进行,这种方法是把测试对象看作一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合功能说明。因此,黑盒测试又称功能测试

白盒测试:软件的白盒测试是对软件的过程细节做细致的检查。这种方法是把测试对象看作一个打开的盒子,它允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序的所有逻辑路径进行测试,通过在不同点检查程序状态,确定实际状态是否与预期的状态一致。因此,白盒测试又称结构测试。

没有junit测试时的缺陷

  • 测试一定要走main方法,是程序的入口,main方法的格式必须不能写错
  • 要是在同一个main方法中测试的话,那么不需要测试的东西必须注释掉
  • 测试逻辑如果分开的话,需要定义多个测试类,麻烦
  • 业务逻辑和测试代码都混淆了

关于测试

  • 一般测试和业务分离,分离为不同的包,名字建议为:公司域名倒写 test,以后的测试类都放在这个包下
  • 测试类的名字要见名知意
  • 测试类可以独立运行,不依托于main方法
  • 测试方法参数为无参,返回值为void
  • 测试方法定义完后不能独立运行,必须要在方法前加注解@test并导入junit环境
  • 判定结果(绿色:正常;红色:异常)
  • 即使出现绿色效果,也不意味着测试通过,因为代码中可能出现问题,解决方法:加入断言

断言

语法:assert.assertequals(期望结果,实际结果);

作用:当期望结果与实际结果不符,那么就抛出异常 

    @test
    public void testout(){
        system.out.println("测试开启");
        //0,1的随机数
        long round = math.round(math.random());
        //加入断言,若真实值不等于期望值则抛出异常
        //第一个参数:预测结果    第二个参数:实际结果
        assert.assertequals(1, round);
    }

@before与@after

@before:某一测试方法中若加入了@before注解以后,那么此方法中的功能会在测试方法执行前先执行

@after:某一测试方法中若加入了@after注解以后,那么此方法中的功能会在测试方法执行后执行

public class test1 {
    @before
    public void init(){
        system.out.println("测试方法开始了");
    }
    @after
    public void close(){
        system.out.println("测试方法结束了");
    }
    @test
    public void test1(){
        system.out.println("测试1执行中……");
    }
    @test
    public void test2(){
        system.out.println("测试2执行中……");
    }
}

注解:注解其实就是代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取并执行相应的处理。通过使用注解,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具,可以通过这些补充信息进行验证或者进行部署

注解开发优势:现在主流开发都是基于注解方式,代码量少,框架可以根据注解去自动生成很多代码,从而减少代码量,程序更易读,如最火爆的springboot就是完全基于注解技术实现的。

注意:

  • 使用注解时要在其前面加@符号,并把注解当成一个修饰符使用。用于修饰它支持的程序元素
  • 注解一般和反射配套使用(就是一个标记,被读到便可修改相关内容)

注解分类

  1. jdk自带注解
  2. 元注解
  3. 自定义注解

jdk注解

  • @override:用来标识此方法是重写的方法
  • @deprecated:用于表示修饰的元素(类、方法、构造器、属性)已过时
  • @suppresswarnings(“unused”)忽略警告(不仅可以放在类上也可以放在方法上)
  • @safevararys:堆污染

元注解

含义:用来描述注解的注解

  • @target:表明注解用在哪,类上?方法上?
  • @retention:注解的生命周期(runtime>class>source)
  • @inherited:父类加上该注解修饰的注解,那么子类也相当于加上该注解修饰的注解
  • @documented:生成javadoc时会包含该注解
  • @repeatable:注解为可重复型注解(就是可以在一个地方放多个) 

自定义注解格式

@target({elementtype.method,elementtype.type})//可以加在方法&类上——用来表示元注解
@retention(retentionpolicy.runtime)//到运行时都有效
@interface 注解名{
    属性类型 属性名1() [default 属性值1];
    属性类型 属性名2() [default 属性值2];//[]内部的东西代表可以不写
}
//下面以rice注解为例

注意:

  • 元注解应定义在注解上面
  • 定义注解只能使用public/默认修饰符
  • 注解内部的属性可以为0个或多个
  • 内部没有定义参数的注解叫做标记,内部定义参数的注解叫做元数据
  • 使用@interface自定义注解时,自动继承了java.lang.annotation.annotation接口 

@target(属性)

属性值内部可选项:

  • element.type:表明此注解可以用在类上
  • element.method:表明此注解可以用在方法上
  • element.field:表明此注解可以用在字段或属性上
  • element.annotation_type:表明此注解可以用在注解类型上
  • element.constructor:表明此注解可以用在构造函数
  • element.local_variable:表明此注解可以用在局部变量上
  • element.package:表明此注解可以用在包声明上
  • element.parameter:表明此注解可以用在方法的参数上

注意:

  • 如果没规定使用位置的注解,则他放到哪都可以
  • 注解在同包中有效,如果要在不同包中有效则需要设置public属性(一个源文件中只能有一个public类)
  • 属性名为value,属性值为1个数组,如果有多个可选项那么总体用{}包裹起来(也可以写成value={})中间用逗号隔开 

@retention(retentionpolicy.属性名)

属性名:

  • source:在源文件中有效(当java文件编译成.class文件时被遗弃)
  • class:在class文件中有效(当jvm加载class文件时被遗弃)
  • runtime:在运行时都有效

注意:

  • 属性名只能三选一 
  • 如果注解没有加@retention元注解,那么相当于默认的注解就是在class文件中有效
  • 生命周期排序:runtime>class>source

注解的内部属性

注解属性的类型:基本数据类型、string类型、枚举类型、注解类型、以上类型的数组。

普通属性

注解属性的定义:int age();

注解的属性都可以设置默认值:int age() default 0;

数组类型注解属性定义

  • 设置默认值:int[] ages() default {1,2,3,4,5,6}; 
  • 不设置默认值:int[] age();

注意:

  • 如果不设置默认值则使用注解时必须给其属性赋值eg:@rice(age=8)、eg:@rice(ages={1,2,3,4,5,6}) 
  • 当有多个内部属性没有设置默认值是,要想使用注解,则需要将多个属性赋值,多个属性之间用逗号隔开
  • 如果此属性有了默认值,同时在使用注解时也给此属性赋予了新值,则默认值会被新值覆盖。

特殊属性value

设置属性:

  • 不设默认值:int value();
  • 设置默认值:int value() default 0;

使用:

  • 单个属性:@rice(value=5)可以简写成@rice(5)
  • 多个属性:@rice(age=8,value=5)不能简写

注意:特殊属性的定义与别的属性相同,主要是使用方式不同(比如单个属性的话相对于普通属性可以简写,但是多个属性不行)

含义:一枚一枚的列举出来,但是个数是有限的、能穷尽的

自定义枚举类

定义枚举类

public class season {
    //属性
   private final string seasonname;//季节名字
   private final string seasondesc;//季节描述
    //利用构造器对属性赋值
    //构造器私有化,外界不能调用这个构造器,只能season自己调用
    private season(string seasonname,string seasondesc){
        this.seasonname=seasonname;
        this.seasondesc=seasondesc;
    }
    //提供枚举类有限的,确定的对象——外界可以通过类名直接调用获得对象
    public static final season spring=new season("春天","春暖花开");
    public static final season summer=new season("夏天","烈日炎炎");
    public static final season autumn=new season("秋天","硕果累累");
    public static final season winter=new season("冬天","冰天雪地");
    //提供get方法,外界可以获取对象属性
    public string getseasonname() {
        return seasonname;
    }
    public string getseasondesc() {
        return seasondesc;
    }
    @override
    public string tostring() {
        return "season{"  
                "seasonname='"   seasonname   '\''  
                ", seasondesc='"   seasondesc   '\''  
                '}';
    }
}

测试枚举类

public class test1 {
    public static void main(string[] args) {
        //获取枚举对象
        season summer = season.summer;
        system.out.println(summer.tostring());//season{seasonname='夏天', seasondesc='烈日炎炎'}
        system.out.println(summer.getseasonname());//夏天
        system.out.println(summer.getseasondesc());//烈日炎炎
    }
}

enum关键字创建枚举类

枚举类结构(用例)

public enum season {
    //提供枚举类有限的,确定的对象——外界可以通过类名直接调用获得对象——>enum枚举类要求对象放在最开始的位置上
    spring("春天","春暖花开"),
    summer("夏天","烈日炎炎"),
    autumn("秋天","硕果累累"),
    winter("冬天","冰天雪地");
    //属性名
   private final string seasonname;//季节名字
   private final string seasondesc;//季节描述
    //利用构造器对属性赋值
    //构造器私有化,外界不能调用这个构造器,只能season自己调用
    private season(string seasonname, string seasondesc){
        this.seasonname=seasonname;
        this.seasondesc=seasondesc;
    }
    //提供get方法,外界可以获取对象属性
    public string getseasonname() {
        return seasonname;
    }
    public string getseasondesc() {
        return seasondesc;
    }
}

注意:

  • 以enum关键字定义枚举类
  • 枚举类提供的枚举对象必须放在结构的最上面,并且多个对象之间用逗号隔开,最后的对象用分号结束
  • 枚举对象可以通过类名.枚举对象名直接调用
  • 枚举对象的属性可以通过get方法直接获取
  • 以enum关键字定义的枚举类上层的父类为java.lang.enum,并且enum类对tostring方法进行了重写,重写后的tostring方法直接返回对应的枚举对象名

枚举类测试

public class test {
    public static void main(string[] args) {
        season autumn = season.autumn;
        system.out.println(autumn);//autumn
        system.out.println(autumn.getseasonname());//秋天
    }
}

空参枚举对象的枚举类

public enum season {
    //这里面一共4个枚举对象
    spring,
    summer,
    autumn,
    winter;
}

理解:因为此枚举类底层没有属性、构造器、get方法,本来枚举对象应写成对象名(),但是()在没有属性的情况下也可以省略

枚举类的常用方法

tostring

语法:枚举对象.tostring()

返回值:枚举对象名

        season autumn = season.autumn;
        system.out.println(autumn.tostring());//autumn

values

语法:枚举类名.values()

返回值:所有枚举对象的数组

        season[] values = season.values();
        system.out.println(arrays.tostring(values));//[spring, summer, autumn, winter]

valueof

语法:枚举类名.valueof("枚举对象名")

返回值:对应的枚举对象

        season spring = season.valueof("spring");
        system.out.println(spring);//spring

枚举类实现接口

前言:枚举类实现接口可以让枚举类的每个枚举对象都实现接口

接口

public interface testinterface {
    void show();
}

枚举类

public enum people implements testinterface {
    man{
        @override
        public void show() {
            system.out.println("男人");
        }
    },
    woman{
        @override
        public void show() {
            system.out.println("女人");
        }
    };
}

测试类

    public static void main(string[] args) {
        people man = people.man;
        man.show();//男人
        people woman = people.woman;
        woman.show();//女人
    }
网站地图