单元测试junit4

一、什么是单元测试

写了个类,要给别人用,会不会有bug?测试一下。
单元测试是保障业务代码质量的非常有效工具,也是提高代码可靠性的必要手段。单元测试是编写测试代码,应该准确、快速地保证程序基本模块的正确性。
用main方法测试的问题:不能一起运行,大多数情况下需要人为的观察输出确定是否正确。

二、junit4入门

1、Eclipse自带junit包,也可以导入最新的junit包,最好是自己导入最新的包。下载地址:https://github.com/junit-team/junit4/wiki/Download-and-Install

2、新建一个Test类:New-->JunitTest Case-->在Junit Test Case界面中,选New Junit 4 test , Name一般为要被测试的类名+Test,Class under test可以选对哪个类进行测试、对这个类的哪些方法测试。-->Finish

3、测试的类和开发的类分开放,建议测试类放在test包中,使用Test作为类名的后缀,测试方法使用test作为方法名的前缀。

4、静态引入:比如import static org.junit.Assert.*; 静态引入一个类,类里面有很多静态方法,可以直接调用这个类里面的静态方法,而不用在其前面加 '类名.'

5、可以在测试类上或测试方法-->右键-->Run As-->Junit Test

6、测试通过的界面

7、测试失败的界面

JUnit 将测试失败的情况分为两种:failure和 error。Failure 一般由单元测试使用的断言方法判断失败引起,它表示在测试点发现了问题;而 error 则是由代码异常引起,这是测试目的之外的发现,它可能产生于测试代码本身的错误,也可能是被测试代码中的一个隐藏的 bug。

8、Assert断言

①Assert类里面有很多静态方法,可查阅相关文档:https://junit.org/junit4/javadoc/latest/org/junit/Assert.html

扫描二维码关注公众号,回复: 2665146 查看本文章

②有的函数的第一个参数String message在断言没有通过,会显示出来,用来自定义提示错误。列如assertEquals(String message, double expected, double actual)

③assertThat可以替代其他所有的assert   

    assertThat(T actual,org.hamcrest.Matcher<T> matcher)
    assertThat(String reason,T actual,org.hamcrest.Matcher<T> matcher)

    需要hamcrest-cose-x.jar和hamcrest-library-x.jar,使用了这两个包后,junit包最好不要用eclipse自带的,会出错。包的下载地址:http://search.maven.org/#search|ga|1|g%3Aorg.hamcrest

    hamcrest帮助文档http://hamcrest.org/JavaHamcrest/javadoc/2.0.0.0/

    Matcher常用的方法见文章第四大点

三、junit4注解

1、测试方法

@Test表示是测试方法,测试方法必须使用注解 org.junit.Test 修饰。测试方法必须使用 public void 修饰,而且不能带有任何参数。

2、异常以及时间测试

注解 org.junit.Test 中有两个非常有用的参数:expected 和 timeout。参数 expected 代表测试方法期望抛出指定的异常,如果运行测试并没有抛出这个异常,则JUnit 会认为这个测试没有通过。这为验证被测试方法在错误的情况下是否会抛出预定的异常提供了便利。

另一个参数 timeout,指定被测试方法被允许运行的最长时间应该是多少,如果测试方法运行时间超过了指定的毫秒数,则 JUnit 认为测试失败。这个参数对于性能测试有一定的帮助。

3、忽略测试方法

注解 org.junit.Ignore 用于暂时忽略某个测试方法,因为有时候由于测试环境受限,并不能保证每一个测试方法都能正确运行。

4、Fixture

Fixture是指在执行一个或者多个测试方法时需要的一系列公共资源或者数据,例如测试环境,测试数据等等。JUnit 专门提供了设置公共 Fixture 的方法,同一测试类中的所有测试方法都可以共用它来初始化 Fixture 和注销 Fixture。

①方法级别的Fixture:

使用注解 org,junit.Before 修饰用于初始化 Fixture 的方法。每一个测试方法之前运行
使用注解 org.junit.After 修饰用于注销 Fixture 的方法。每一个测试方法之后运行
保证这两种方法都使用 public void 修饰,而且不能带有任何参数。

②类级别的 Fixture
使用注解 org,junit.BeforeClass修饰用于初始Fixture 的方法。所有测试方法开始之前运行,它比较适合加载配置文件,进行初始化等等
使用注解 org.junit.AfterClass 修饰用于注销 Fixture 的方法。所有测试方法开始之后运行,通常用来对资源的清理,如关闭数据库的连接
保证这两种方法都使用 public static void 修饰,而且不能带有任何参数。

5、测试运行器

可以定制自己的运行器(所有的运行器都继承自org.junit.runner.Runner)
使用注解 org.junit.runner.RunWith 在测试类上显式的声明要使用的运行器

6、测试套件

Unit 提供的一种批量运行测试类的方法,测试套件的写法遵循以下规则:

    ①创建一个空类作为测试套件的入口。
    ②使用注解 org.junit.runner.RunWith 和org.junit.runners.Suite.SuiteClasses 修饰这个空类。
    ③将 org.junit.runners.Suite 作为参数传入注解 RunWith,以提示 JUnit 为此类使用套件运行器执行。
    ④将需要放入此测试套件的测试类组成数组作为注解 SuiteClasses 的参数。
    ⑤保证这个空类使用 public 修饰,而且存在公开的不带有任何参数的构造函数。

@RunWith(Suite.class)  
@Suite.SuiteClasses({TaskTest1.class,TaskTest2.class,...})  
public class SuiteTest { }

7、多个测试类同时运行

选择任意一个测试类-->Run As-->RunConfigurations-->选择Run all tests in the selected project, package or source folder-->Run

8、参数化测试

参数化测试将测试方法中相同的代码结构提取出来,提高代码的重用度。参数化测试的编写:

    ①为准备使用参数化测试的测试类指定特殊的运行器 org.junit.runners.Parameterized。
    ②为测试类声明几个变量,分别用于存放期望值和测试所用数据。
    ③为测试类声明一个使用注解 org.junit.runners.Parameterized.Parameters 修饰的,返回值为 java.util.Collection 的公共静态方法,并在此方法中初始化所有需要测试的参数对。
    ④为测试类声明一个带有参数的公共构造函数,并在其中为第二个环节中声明的几个变量赋值。
    ⑤编写测试方法,使用定义的变量作为参数进行测试。

// 第一步
@RunWith(Parameterized.class)
public class TestWordDealUtilWithParam
{
    // 第二步
    private String expected;
    private String target;
    // 第三步
    @Parameters
    public static Collection words()
    {
        return Arrays.asList(new Object[][]
        {
            { "employee_info", "employeeInfo" }, // 测试一般的处理情况
            { null, null }, // 测试 null 时的处理情况
        });
    }
    // 第四步
    public TestWordDealUtilWithParam(String expected, String target)
    {
        this.expected = expected;
        this.target = target;
    }
    // 第五步
    @Test
    public void wordFormat4DB()
    {
        assertEquals(expected, WordDealUtil.wordFormat4DB(target));
    }
}
四、assertThat

①一般匹配符
1、assertThat( testedNumber, allOf( greaterThan(8), lessThan(16) ) );
注释: allOf匹配符表明如果接下来的所有条件必须都成立测试才通过,相当于“与”(&&)
2、assertThat( testedNumber, anyOf( greaterThan(16), lessThan(8) ) );
注释:anyOf匹配符表明如果接下来的所有条件只要有一个成立则测试通过,相当于“或”(||)
3、assertThat( testedNumber, anything() );
注释:anything匹配符表明无论什么条件,永远为true
4、assertThat( testedString, is( "developerWorks" ) );
注释: is匹配符表明如果前面待测的object等于后面给出的object,则测试通过
5、assertThat( testedString, not( "developerWorks" ) );
注释:not匹配符和is匹配符正好相反,表明如果前面待测的object不等于后面给出的object,则测试通过

②字符串相关匹配符
1、assertThat( testedString, containsString( "developerWorks" ) );
注释:containsString匹配符表明如果测试的字符串testedString包含子字符串"developerWorks"则测试通过
2、assertThat( testedString, endsWith( "developerWorks" ) );
注释:endsWith匹配符表明如果测试的字符串testedString以子字符串"developerWorks"结尾则测试通过
3、assertThat( testedString, startsWith( "developerWorks" ) );
注释:startsWith匹配符表明如果测试的字符串testedString以子字符串"developerWorks"开始则测试通过
4、assertThat( testedValue, equalTo( expectedValue ) );
注释: equalTo匹配符表明如果测试的testedValue等于expectedValue则测试通过,equalTo可以测试数值之间,字
符串之间和对象之间是否相等,相当于Object的equals方法
5、assertThat( testedString, equalToIgnoringCase( "developerWorks" ) );
注释:equalToIgnoringCase匹配符表明如果测试的字符串testedString在忽略大小写的情况下等于"developerWorks"则测试通过
6、assertThat( testedString, equalToIgnoringWhiteSpace( "developerWorks" ) );
注释:equalToIgnoringWhiteSpace匹配符表明如果测试的字符串testedString在忽略头尾的任意个空格的情况下等
于"developerWorks"则测试通过,注意:字符串中的空格不能被忽略

③数值相关匹配符
1、assertThat( testedDouble, closeTo( 20.0, 0.5 ) );
注释:closeTo匹配符表明如果所测试的浮点型数testedDouble在20.0±0.5范围之内则测试通过
2、assertThat( testedNumber, greaterThan(16.0) );
注释:greaterThan匹配符表明如果所测试的数值testedNumber大于16.0则测试通过
3、assertThat( testedNumber, lessThan (16.0) );
注释:lessThan匹配符表明如果所测试的数值testedNumber小于16.0则测试通过
4、assertThat( testedNumber, greaterThanOrEqualTo (16.0) );
注释: greaterThanOrEqualTo匹配符表明如果所测试的数值testedNumber大于等于16.0则测试通过
5、assertThat( testedNumber, lessThanOrEqualTo (16.0) );

注释:lessThanOrEqualTo匹配符表明如果所测试的数值testedNumber小于等于16.0则测试通过

④collection相关匹配符
1、assertThat( mapObject, hasEntry( "key", "value" ) );
注释:hasEntry匹配符表明如果测试的Map对象mapObject含有一个键值为"key"对应元素值为"value"的Entry项则测试通过
2、assertThat( iterableObject, hasItem ( "element" ) );
注释:hasItem匹配符表明如果测试的迭代对象iterableObject含有元素“element”项则测试通过
3、assertThat( mapObject, hasKey ( "key" ) );
注释: hasKey匹配符表明如果测试的Map对象mapObject含有键值“key”则测试通过
4、assertThat( mapObject, hasValue ( "key" ) );
注释:hasValue匹配符表明如果测试的Map对象mapObject含有元素值“value”则测试通过

五、软件测试一些概念

UT是单元测试,Unit Test;
单元测试任务包括:1 模块接口测试;2 模块局部数据结构测试;3 模块边界条件测试;4 模块中所有独立执行通路测试;5 模块的各条错误处理通路测试。;

IT是集成测试,Integration Test;
集成测试阶段是以黑盒法为主,在自底向上集成的早期,白盒法测试占一定的比例,随着集成测试的不断深入,这种比例在测试过程中将越来越少,渐渐地,黑盒法测试占据主导地位。

ST是系统测试,System Test;
从技术角度看,系统测试是整个测试阶段的最后一步,所有的开发和测试在这一点上集中表现为生成一个具有一定功能的软件系统。该阶段主要对系统的准确性及完整性等方面进行测试。主要进行:功能确认测试、运行测试、强度测试、恢复测试、安全性测试等。系统测试的测试人员由测试组成员(或质量保证人员)或测试组成员与用户共同测试。在整个系统开发完成,即将交付用户使用前进行。在这一阶段,完全采用黑盒法对整个系统进行测试。

UAT是验收测试,User Acceptance Test;
验收测试是向未来的用户表明系统能够像预定要求那样工作。经集成测试后,已经按照设计把所有的模块组装成一个完整的软件系统,接口错误也已经基本排除了,接着就应该进一步验证软件的有效性,这就是验收测试的任务,即软件的功能和性能如同用户所合理期待的那样。

功能测试
功能测试分三个阶段,第一个阶段自测,第二个阶段交叉测试,最后回归测试。
交叉测试按字面意思理解就是把测试人员所测试的模块交换测试。回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。回归测试是指重复以前的全部或部分的相同测试,回归测试的重心,以关键性模组为核心。


猜你喜欢

转载自blog.csdn.net/qq_29837161/article/details/80813074