在实际编码测试中,我们有的时候需要对一个方法进行多次测试,那么怎么办呢?这个问题和测试套件解决的方案一样,我们总不能不停的去右键run as,那怎么办呢?还好伟大的junit帮我们想到了。

OK,现在我们开始来写一个例子:

测试源码:

package org.linkinpark.junit.testjunit;

/**
* @创建作者: LinkinPark
* @创建时间: 2016年2月5日
* @功能描述: 写一个测试源码
*/
public class Linkin
{
public String test(String str)
{
return str + "。。。";
} }

测试代码:

package org.linkinpark.junit.testjunit;

import org.junit.Assert;

import junit.extensions.RepeatedTest;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite; public class LinkinTest extends TestCase
{
public LinkinTest()
{
super();
} public LinkinTest(String name)
{
super(name);
} public static Test suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new RepeatedTest(new LinkinTest("test"), 20));
return suite;
} public void test() throws Exception
{
Linkin test = new Linkin();
String str = test.test("LinkinPark");
Assert.assertEquals("LinkinPark。。。", str);
} }

现在我们运行一下,然后我们看下junit控制台什么情况?

OK,测试通过,我们也看到了,我们写的这个test测试方法执行20次,现在我们既然会使用junit来进行方法的重复测试了。那么junit到底是怎么实现的呢?我在前面的junit源码解析整理中没有整理到这部分。

那我们现在一起来看一下:

上面的测试代码使用junit38测试套件,就是自定义了Suite()方法,我不知道junit4X系列中这个重复测试能不能用,个人觉得好像是不行。先言归正传吧。在我们自己定义的Suite类中,我们调用addTest()方法来添加用例,注意这里添加的是RepeatedTest类,那我们现在就来看看这个类的源码:

RepeatedTest类的父类TestDecorator源码如下:

package org.linkinpark.commons.extensions;

import org.linkinpark.commons.framework.Test;
import org.linkinpark.commons.framework.TestResult;
import org.linkinpark.junit.Assert; /**
* @创建作者: LinkinPark
* @创建时间: 2016年2月5日
* @功能描述: 测试装饰器父类
*/
public class TestDecorator extends Assert implements Test
{
protected Test fTest; // 封装一个测试用例 public TestDecorator(Test test)
{
fTest = test;
} /**
* The basic run behaviour.
*/
public void basicRun(TestResult result)
{
fTest.run(result);
} public int countTestCases()
{
return fTest.countTestCases();
} public void run(TestResult result)
{
basicRun(result);
} @Override
public String toString()
{
return fTest.toString();
} public Test getTest()
{
return fTest;
}
}

RepeatedTest源码如下:

package org.linkinpark.commons.extensions;

import org.linkinpark.commons.framework.Test;
import org.linkinpark.commons.framework.TestResult; /**
* @创建作者: LinkinPark
* @创建时间: 2016年2月5日
* @功能描述: 重复测试Test容器
*/
public class RepeatedTest extends TestDecorator
{
private int fTimesRepeat; public RepeatedTest(Test test, int repeat)
{
super(test);
if (repeat < 0)
{
throw new IllegalArgumentException("Repetition count must be >= 0");
}
fTimesRepeat = repeat;
} @Override
public int countTestCases()
{
return super.countTestCases() * fTimesRepeat;
} @Override
public void run(TestResult result)
{
for (int i = 0; i < fTimesRepeat; i++)
{
if (result.shouldStop())
{
break;
}
super.run(result);
}
} @Override
public String toString()
{
return super.toString() + "(repeated)";
}
}

2篇源码分析一下:

在TestDecorator父类中,封装一个测试用例Test。在前面的一系列junit源码分析中,我们知道了,一个测试用例的执行,实际是TestCase类中的run()方法。其实这里的这个TestDecorator可以理解为类似于Suite,他是一个测试用例的容器。

由于该类同样实现了Test接口,所以执行测试也同样是run()方法,那么我们看到了该类的run()方法实际上调用的也是Test接口的run()方法,这么说大家明白了,其实这里只是在TestCase类上面嫁入一层,其实也是适配器模式。

然后现在我们来看下RepeatedTest类,该子类重写了父类的run()方法,只不过加了一个for循环来重复调用父类执行测试的方法,这样子就实现了多次执行测试的目的。源码不难,我们在研究junit的源码过程中不得不佩服junit的设计。这块也是我之所以

要去看一些开源框架源码的目的,之后我会自己写一套自己的web框架,到时候也会把这些好的思想加入进去,使自己的代码真正的高内聚,低耦合。



OK,在看前面的源码过程中,我还发现了一个类,TestSetup,同样也是TestDecorator的子类。大概的看了下源码,也明白了该类的使用。

package org.linkinpark.commons.extensions;

import org.linkinpark.commons.framework.Protectable;
import org.linkinpark.commons.framework.Test;
import org.linkinpark.commons.framework.TestResult; /**
* A Decorator to set up and tear down additional fixture state. Subclass
* TestSetup and insert it into your tests when you want to set up additional
* state once before the tests are run.
*/
public class TestSetup extends TestDecorator
{ public TestSetup(Test test)
{
super(test);
} @Override
public void run(final TestResult result)
{
Protectable p = new Protectable()
{
public void protect() throws Exception
{
setUp();
basicRun(result);
tearDown();
}
};
result.runProtected(this, p);
} /**
* Sets up the fixture. Override to set up additional fixture state.
*/
protected void setUp() throws Exception
{
} /**
* Tears down the fixture. Override to tear down the additional fixture
* state.
*/
protected void tearDown() throws Exception
{
}
}

明显的如果我们在测试类中存在继承关系的时候,我们当然可以直接重写setUp()和tearDown()方法来执行测试前后的初始化,同时我们也可以使用装饰器来封装一次测试用例,同样的效果。我看过junit源码中自带的测试类,框架主要用这个类来做一些异常和失败的统计。OK,我们学段代码来试一下好了。

演示代码如下:

package org.linkinpark.commons.textui;

import org.linkinpark.commons.framework.TestCase;
import org.linkinpark.junit.Assert; public class LinkinTest extends TestCase
{
public LinkinTest()
{
} public LinkinTest(String methodName)
{
super(methodName);
} public void setUp()
{
System.err.println("这里是父类定义的setUp()");
} public void testLinkin4Normal()
{
final String str = "林肯:这里是自己的被测试的正确代码";
Assert.assertEquals(str, str);
} }

然后我们派生一个子类,主要在子类执行main方法时候不要直接运行,写一个suite静态方法来传入一个TestSetup类型的Test,然后我们来看下效果。

package org.linkinpark.commons.textui;

import org.linkinpark.commons.extensions.TestSetup;
import org.linkinpark.commons.framework.Test;
import org.linkinpark.commons.framework.TestSuite; public class SonLinkinTest extends LinkinTest
{ public static Test suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new TestSetup(new LinkinTest()));
return suite;
} public void tearDown()
{
System.err.println("这里是子类定义的tearDown()");
} public static void main(String[] args)
{
TestRunner.run(SonLinkinTest.class);
} }

最后我们来看下控制台的输出:

###########开始迭代运行整套测试,互相独立###########
第一步:框架开始打印日志====
~~~~~~~~~~~~~~~~~~~~~~~
第二步:框架开始运行测试====
这里是父类定义的setUp()
框架开始执行测试,执行的方法是-->public void org.linkinpark.commons.textui.LinkinTest.testLinkin4Normal()
框架结束执行测试,执行的方法是-->public void org.linkinpark.commons.textui.LinkinTest.testLinkin4Normal()
这里是子类定义的tearDown()
第三步:框架结束运行测试====
~~~~~~~~~~~~~~~~~~~~~~~
第四步:框架开始统计时间====
耗时:0.023秒
第五步:框架开始统计结果====
结果:OK,木问题!
统计:一共执行了1个测试用例
第六步:框架结束整个测试====

junit测试延伸--方法的重复测试的更多相关文章

  1. junit测试延伸--私有方法测试

    关于junit测试的延伸,这里有类概念级别的测试,继承类的测试,接口的测试,抽象类的测试,关于这些类级别的测试,这里我就不做多的赘述了. 关于上面的几个测试就是说,我们不应该单纯的去测试类中的一些方法 ...

  2. 为什么使用Junit Test而不用普通java main方法来完成测试?

    因为在程序里边,一个接口对应一个实现方法,而在接口中常常会定义相关的很多方法,所以在测试的时候,如果都在main方法里边进行测试,main方法就会显得臃肿,而且不便于以后其他人测试以及查看测试数据,用 ...

  3. 【drp 11】使用Junit简单测试接口方法

    一.Junit简介 JUnit是一个Java语言的单元测试框架.它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个. JUn ...

  4. JUnit 3.8 通过反射测试私有方法

    测试私有(private)的方法有两种: 1)把目标类的私有方法(修饰符:private)修改为(public),不推荐,因为修改了源程序不佳 2)通过反射 (推荐) 代码演示: 目标程序 Priva ...

  5. JUnit5的条件测试、嵌套测试、重复测试

    条件测试 JUnit5支持条件注解,根据布尔值判断是否执行测试. 自定义条件 @EnabledIf和@DisabledIf注解用来设置自定义条件,示例: @Test @EnabledIf(" ...

  6. Spring的Bean的生命周期方法执行顺序测试

    通过一个简单的Maven工程来演示Spring的Bean生命周期函数的执行顺序. 下面是工程的目录结构: 直接贴代码: pom.xml文件内容: <?xml version="1.0& ...

  7. 无所不能的PowerMock,mock私有方法,静态方法,测试私有方法,final类

    1.为什么要用mock 我的一本书的解释: (1)创建所需的DB数据可能需要很长时间,如:调用别的接口,模拟很多数据 (2)调用第三方API接口,测试很慢, (3)编写满足所有外部依赖的测试可能很复杂 ...

  8. Testing - 测试基础 - 方法

    选择和使用测试方法和工具 按照测试需求用途(或测试技巧)选择 在软件开发生命周期和软件测试流程中适当地选择 按照测试人员实际技能选择 选择可提供的和可执行的 测试方法 类别及技巧 目标 使用方法 举例 ...

  9. Xcode 真机测试破解方法(转加修改)xcode 4.3 通过

    Xcode 真机测试破解方法(转加修改)xcode 4.3 通过 生成本机证书 应用程序->实用工具->钥匙串访问 菜单:钥匙串访问->证书助理->创建证书, 然后按以下图片顺 ...

随机推荐

  1. Java框架之Hibernate(四)

    本文主要介绍: 1 悲观锁和乐观锁 2 使用版本号控制并发访问 3 flush方法和批量更新的问题 4 DetachedCriteria 5 N + 1 次查询 6 使用sql进行查询 7 注解方式 ...

  2. linux 实时同步inotify

    #实时同步inotify 1.inotify简介inotify是一种强大的,细腻度的,异步的文件系统事件监控机制,linux内核从2.6.13起,加入了inotify支持,通过INOTIFY可以监控文 ...

  3. 转深入理解 AngularJS 的 Scope作用域

    文章转载英文:what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs 中文:http://www. ...

  4. Error:C:\Users\issuser\AndroidStudioProjects\SQLiteDemo1\.gradle\buildOutputCleanup\cache.properties (系统找不到指定的文件。)

    android studio报下图中的这个错误的解决办法: 解决办法: 1.删除掉下图中标记的2个文件夹 2.将下图标记的文件的文件名重命名,把最后的后缀.lock去掉,因为加上了这个后缀,所以提示找 ...

  5. LeetCode第[1]题(Java):Two Sum 标签:Array

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  6. https 与 http

    HTTPS,HTTP over SSL,SSL是解决传输层安全问题的网络协议,其核心是基于公钥密码学理论实现了对服务器身份认证,数据的私密性保护以及对数据完整性的校验等功能. SSL协议在HTTP请求 ...

  7. Nginx概述和安装(1)

    一.Nginx概述 Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 是由 I ...

  8. iframe标签里面的页面元素只读

    iframe标签里面的页面元素只读,可以通过设置一个只读的透明div进行遮罩实现. html代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1 ...

  9. dead loop、continue & break、while...else语句

    Dead loop 死循环,一经触发就会永远运行下去. continue & break 如果在循环过程中,因为某些原因,你不想继续循环了,就要用到break 或 continue语句. br ...

  10. Timus Online Judge:ural:1006. Square Frames

    原题链接:http://acm.timus.ru/problem.aspx?space=1&num=1006 看到题第一反应:这玩意怎么读入…… 本地的话因为是全角字符,会占两个位置,所以需要 ...