您的位置:首页 > 编程语言 > Java开发

Junit测试框架初探

2017-10-05 10:34 190 查看
   Junit是用于编写可复用测试集的简单框架,是基于xUnit的,xUnit是一套基于测试驱动开发的测试框架,包括PythonUnit,用于Python的测试,CppUnit用于C++的测试,以及要要学的Java的单元测试JUnit。其可以针对性的对程序进行测试,减少代码的漏洞。当然也可以使用Main方法进行测试,输出结果并不友好,而且需要程序员自己去判断错误的来源等。

    其中我们可以从官网获取相关的jar包,如:junit包和hamcrest-core.jar包,前者是需要用到的,后者提供增强的功能,JUint3中所有的方法必须加上@Test前缀才可以进行测试,并且,JUnit3必须继承junit.framework.TestCase类来实现。

    闲话不多说直接案例:

1.快速入门

    假设我们需要测试一个模块中的方法,这个模块中包含了基本的四则运算,加减乘除等,我们将此类命名为:Calculate

public class Calculate {

public int add (int a ,int b){
return a+b;
}

public int subtract(int a, int b){
return a-b;
}
public int multiply(int a, int b){
return a*b;
}
public int divide(int a,int b){
return a/b;
}

}
     需要对这个类中的方法进行测试,当然也可以通过主函数中将类实例化后调用方法,但是这样需要过多的编码,而且测试也不方便,然而,JUint则可以很方便的帮助开发者进行单元模块等的测试:

将测试的方法命名为:CalculateTest

public class CalculateTest {

@Test
public void testAdd(){
assertEquals(6, new Calculate().add(3,3));
}

@Test
public void testsubtract(){
assertEquals(3, new Calculate().subtract(5,2));
}

@Test
public void testMultiply(){
assertEquals(4, new Calculate().multiply(2, 2));
}

@Test
public void testDivide(){
assertEquals(3, new Calculate().divide(6, 2));
}
     有以下注意事项:

1.@Test注解修饰的方法不能有返回值,且要测试的方法必须要使用@Test进行注释;

2.我们可以将测试类单独的放置到一个文件夹中,当整个项目测试通过并且可以发布之后,可以讲这个文件夹或者是包中的测试类的内容删除掉。

3.  测试类的包的名字和被测试类一致,测试方法之间不能有任何依赖,测试的方法前注意规范,使用test作为前缀,这样便于管理。

4.对于测试完成后弹出的窗口,需要了解以下内容:Failure一般是由单元测试使用的断言方法判断失败所引起的,这表示,测试点发生了问题,说明程序输出的结果和我们预期的不一样,errror是由于异常引起的,他可能产生于代码本身的错误,也可是一个被隐藏的bug,测试不是用来证明是对的,而是用来证明没有错误。

  例如我们可以做一下测试:

public class ErrorAndFaliureTest {

@Test
public void testAdd(){
assertEquals(5, new Calculate().add(3,3));
}
}
当我们测试add方法时,3+3结果应该为6,但我们设置的预期值为5,这时候就会出现6!=5的情况,就会出现Failure,往往这种情况是类似于测试用例那样是由于判断方法的失败引起的,而error则是出现异常:例如6/0;会抛出一个异常,这时候测试结果窗口中就会将方法标记为error。error一般隐藏在代码本身中,可能是一个隐藏的bug。

2.JUnit测试的流程实例:

JUnit测试的流程中上述的简单的测试方法仅是测试流程中一步,还有其他的步骤,例如我们测试的某个类需要在测试之前做一系列的操作,有针对整个测试过程的基本的配置,也有针对每个别测试对象的单独的配置的过程,这时候则需要针对整个过程详细设计流程:

对此,设计一个JunitFlowTest类,这个类包含了整个的测试流程:

public class JunitFlowTest {

@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("this is beforeclass```");
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("this is afterclass```");

}

@Before
public void setUp() throws Exception {
System.out.println("this is before```");

}

@After
public void tearDown() throws Exception {
System.out.println("this is after```");

}
@Test
public void test1(){
System.out.println("this is test1```");

}
@Test
public void test2(){
System.out.println("this is test2```");

}

}
要点:
@BeforeClass修饰的方法会在所有的方法调用之前被执行而且该方法是静态的,所以当测试类被加载后就这就运行它而且内存中仅有一份实例,比较适合加载配置文件,例如我们对Spring框架中的某些方法进行测试,如数据库连接测试,则可以使用这个注解修饰的方法完成数据库文件的配置,以及ApplicationContext或者是Configuration类中的某些配置文件。

@AfterClass所修饰的方法通常用来对资源进行清理,如关闭数据库的连接,释放某些资源。

@Before和@After会在没测测试方法的前后各执行一次,其针对的时被测试对象的某个方法在执行前,或者是执行后的需要做出的某些行为。其会在每个方法执行前和执行后分别调用@Before和@After。

3.使用JUnit的测试套件工具:

 首先为了测试我们新建了3个类,每个类中都有被测试的方法,都使用@Test注解:

public class TaskTest1 {

@Test
public void test() {
System.out.println("this is tasktest1```");
}

}

public class TaskTest2 {

@Test
public void test() {
System.out.println("this is tasktest2```");
}

}


public class TaskTest3 {

@Test
public void test() {
System.out.println("this is tasktest3```");;
}

}


这三个类都需要测试,而如果我们还是用到上面提的到测试方法,则需要创建相应的测试类进行测试,而当类中的方法很多时,针对每一个方法都进行测试则需要编写更多的测试代码,而使用测试套件工具则可以解决这个问题:

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

}

  在这段代码中,需要保证SuitTest类是空类,测试套件就是组织测试类一起运行的, 写一个作为测试套件的入口类,这个类不能包含其它的方法,更改测试运行器,将其更改为Suite.class,将要测试的类作为数组传入到Suite.SuiteClass({}),

核心部分即使在要测试的类中将要测试的方法添加@Test注解,然后添加所示的注解:

@RunWith(Suite.class)
@Suite.SuiteClasses({TaskTest1.class,TaskTest2.class,TaskTest3.class})
4.参数化的测试:

@RunWith(Parameterized.class)
public class ParameterTest {

int expected=0;
int input1=0;
int input2=0;

@Parameters
public static Collection<Object[]> t (){
return Arrays.asList(new Object[][]{
{3,1,2},
{4,2,2}
});
}

public ParameterTest(int expected,int input1,int input2){
this.expected=expected;
this.input1=input1;
this.input2=input2;
}

@Test
public void testAdd(){
assertEquals(expected, new Calculate().add(input1, input2));

}
}

  在ParameterTest类中使用静态方法t来产生Collection<Object[
c385
]>集合类的实例来调用ParameterTest类的构造方法,完成对expected(期望值),input1(输入值1),input2(输入值2)三个值赋值,最后则通过@Test注解的testAdd方法完成测试。

要点:

 1.更改默认的测试运行器,改为@RunWith(Parameterized.class)

 2.声明变量来存放预期值和结果值, 声明一个返回值为Collection的公共静态方法,并使用
3.@Parameter进行修饰,修饰存放参数的变量

4.为测试类声明一个带有参数的公供构造函数,并在其中为之声明变量赋值

5.常用的几个注解分析:

public class AnnotationTest {

@Test(expected=ArithmeticException.class)
//预期会抛出一个算术异常
public void testDivide(){
assertEquals(3, new Calculate().divide(6, 0));
}

@Ignore("ss")
@Test(timeout=2000)
public void testWhile(){
while(true){
System.out.println("run forever```");
}
}

}
总结:

@Test将一个普通的方法修饰成为一个测试方法

@Test(expected=XX.class)

@Test(timeout=毫秒)设置时间,例如测试循环,或者是性能测试的时候会用到

@BeforeClass会在所有的运行方法之前被执行,static修饰

@AfterClass会在所有的运行方法之后被执行,static修饰

@Before 会在每一个测试方法被运行前执行一次

@After会在每一个测试方法运行之后执行一次

@Ignore所修饰的方法会被测试运行期忽略

@RunWith 可以更改测试类的运行器  一般继承org.junit.runner.Runner
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  测试 junit java