`
luogankun
  • 浏览: 19427 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

junit设计模式分析二(组合模式)

阅读更多

为了获得对系统测试的信心,需要运行多个测试用例。通过使用Command模式,JUnit能够方便的运行一个单独的测试用例之后产生测试结果。可是在实际的测试过程中,需要把多个测试用例进行组合成为一个复合的测试用例,当作一个请求发送给JUnit.这样JUnit就会面临一个问题,必须考虑测试请求的类型,是一个单一的TestCase还是一个复合的TestCase,甚至要区分到底有多少个TestCase。这样Junit框架就要完成像下面这样的代码:
if(isSingleTestCase(objectRequest)){
//如果是单个的TestCase,执行run,获得测试结果
(TestCase)objectRequest.run()
}else if(isCompositeTestCase(objectRequest)){
//如果是一个复合TestCase,就要执行不同的操作,然后进行复杂的算法进行分
//解,之后再运行每一个TestCase,最后获得测试结果,同时又要考虑
//如果中间测试出现错误怎么办????、

…………………………
…………………………
}
这会使JUnit必须考虑区分请求(TestCase)的类型(是单个testCase还是复合testCase),而实际上大多数情况下,测试人员认为这两者是一样的。对于这两者的区别使用,又会使测试用例的编写变得更加复杂,难以维护和扩展。于是要考虑,怎样设计JUnit才可以实现不需要区分单个TestCase还是复合TestCase,把它们统一成相同的请求?

 

 

当JUnit不必区分其运行的是一个或多个测试用例时,能够轻松地解决这个问题的模式就是Composite(组合)模式。摘引其意图,"将对象组合成树形结构以表示'部分-整体'的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。"在这里'部分-整体'的层次结构是解决问题的关键,可以把单个的TestCase看作部分,而把复合的TestCase看作整体(称为TestSuit)。这样使用该模式便可以恰到好处得解决了这个难题。

 

组合模式的构成:

1、Component:这是一个抽象角色,它给参加组合的对象规定一个接口。这个角色给出共有的接口和默认的行为。其实就我们的Test接口,它定义出run方法

2、Composite:实现共有接口并维护一个测试用例的集合,它就是复合测试用例TestSuite

3、Leaf:代表参加组合的对象,它没有下级子对象,仅定义出参加组合的原始对象的行为,其实就是单一的测试用例TestCase,它仅实现Test接口的方法

 

其实componsite模式根据所实现的接口类型区分为两种形式,分别称为安全式和透明式。JUnit中使用了安全式的结构,这样在TestCase中没有管理子对象的方法。

 

组合模式的代码实现:

Component:

 

public interface Component {
	public void doSomething();
}

 

Composite:

public class Composite implements Component {

	private List<Component> list = new ArrayList<Component>();

	public void add(Component component) {
		list.add(component);
	}

	public void remove(Component component) {
		list.remove(component);
	}

	public List<Component> getAll() {
		return list;
	}

	public void doSomething() {
		for (Component com : list) {
			com.doSomething();
		}
	}
}

 

 

Leaf:

public class Leaf implements Component {
	public void doSomething() {
		System.out.println("dosomething");
	}
}

 

Client:

public class Client {
	public static void main(String[] args) {
		Component com = new Leaf();
		Component com2 = new Leaf();

		Composite composite = new Composite();

		composite.add(com);
		composite.add(com2);

		composite.doSomething();
	}
}

 

 

composite模式告诉我们要引入一个Component抽象类,为Leaf对象和composite对象定义公共的接口。这个类的基本意图就是定义一个接口。在Java中使用Composite模式时,优先考虑使用接口,而非抽象类,因此引入一个Test接口。当然我们的leaf就是TestCase了。其源代码如下:

public interface Test {
       public abstract void run(TestResult result);
}

public abstract class TestCase extends Assert implements Test {
      public void run(TestResult result) {
	result.run(this);}
}

 

下面,列出Composite源码。将其取名为TestSuit类。TestSuit有一个属性fTests (Vector类型)中保存了其子测试用例,提供addTest方法来实现增加子对象TestCase ,并且还提供testCount 和tests 等方法来操作子对象。最后通过run()方法实现对其子对象进行委托(delegate),最后还提供addTestSuite方法实现递归,构造成树形。

 

public class TestSuite implements Test {
	private Vector fTests= new Vector(10);
	public void addTest(Test test) {
		fTests.addElement(test);
	}
	public void addTestSuite(Class testClass) {
		addTest(new TestSuite(testClass));
	}
	public void run(TestResult result) {
		for (Enumeration e= tests(); e.hasMoreElements(); ) {
	  		if (result.shouldStop() )
	  			break;
			Test test= (Test)e.nextElement();
			runTest(test, result);
		}
	}
	public Enumeration tests() {
		return fTests.elements();
	}}

 注意所有上面的代码是对Test接口进行实现的。由于TestCase和TestSuit两者都符合Test接口,我们可以通过addTestSuite递归地将TestSuite再组合成TestSuite,这样将构成树形结构。所有开发者都能够创建他们自己的TestSuit。测试人员可创建一个组合了这些测试用例的TestSuit来运行它们所有的TestCase。

public static Test suite() {
	TestSuite suite1 = new TestSuite("我的测试TestSuit1");
	TestSuite suite2 = new TestSuite("我的测试TestSuit2");
	suite1.addTestSuite(untitled6.Testmath.class);
	suite2.addTestSuite(untitled6.Testmulti.class);
	suite1.addTest(suite2);
	return suite1;
}

 

效果:
我们来考虑经过使用Composite模式后给系统的架构带来了那些效果:
1、 简化了JUnit的代码   JUnit可以统一处理组合结构TestSuite和单个对象TestCase。使JUnit开发变得简单容易,因为不需要区分部分和整体的区别,不需要写一些充斥着if else的选择语句。
2、定义了TestCase对象和TestSuite的类层次结构基本对象TestCase可以被组合成更复杂的组合对象TestSuite,而这些组合对象又可以被组合,如上个例子,这样不断地递归下去。在程序的代码中,任何使用基本对象的地方都可方便的使用组合对象,大大简化系统维护和开发。
3、使得更容易增加新的类型的TestCase,如下面介绍的Decorate模式来扩展TestCase的功能

 

 

其实junit3.8中用到的组合模式是安全式:

添加Component对象的操作定义在Composite角色中,这样的话Leaf就无需实现这些方法(因为Leaf本身根本不需要实现这些方法)

 

还有一种的透明式:

 添加Component对象的操作定义在Component角色中,这样的话不仅Composite需要实现这些方法,Leaf也需要实现这些方法, 而这些方法对于Leaf来说没有任何意义,不过将系统实现统一起来了,因此对用户来说透明(用户无需区分Composite还是Leaf),因为这些角色中都具备这些方法。

 

透明式的代码实现如下:

Component:

public interface Component {
	public void doSomething();
	public void add(Component component);
	public void remove(Component component) ;
	public List<Component> getAll() ;
}

 

Composite:

public class Composite implements Component {

	private List<Component> list = new ArrayList<Component>();

	public void add(Component component) {
		list.add(component);
	}

	public void remove(Component component) {
		list.remove(component);
	}

	public List<Component> getAll() {
		return list;
	}

	public void doSomething() {
		for (Component com : list) {
			com.doSomething();
		}
	}
}

 

Leaf:

public class Leaf implements Component {
	public void doSomething() {
		System.out.println("dosomething");
	}

	public void add(Component component) {
	}

	public List<Component> getAll() {
		return null;
	}

	public void remove(Component component) {
	}
}

 

Client:

public class Client {
	public static void main(String[] args) {
		Component com = new Leaf();
		Component com2 = new Leaf();

		Component component = new Composite();

		component.add(com);
		component.add(com2);

		component.doSomething();
	}
}

 

 

 

分享到:
评论

相关推荐

    Junit设计模式分析

    在Junit中,设计模式的应用极大地增强了其灵活性和可扩展性。下面我们将深入探讨Junit中涉及到的设计模式及其作用。 1. 工厂模式:JUnit中的`TestSuite`类就是一个典型的工厂模式应用,它根据传入的类或测试方法...

    JUnit设计模式分析

    总之,JUnit的设计模式分析展示了如何将经典设计模式融入实际项目中,以达到简化代码、增强可维护性和提高代码复用性的目的。理解这些模式及其在JUnit中的应用,对于提升Java测试能力及软件开发实践具有重要意义。

    Junit设计模式分析.rar

    《JUnit设计模式分析》 JUnit,作为Java编程领域中最广泛使用的单元测试框架,它的重要性不言而喻。在软件开发过程中,单元测试是确保代码质量、可维护性和可扩展性的重要手段。本分析将深入探讨JUnit的设计模式,...

    Junit设计模式分析.pdf

    以下是一些在JUnit中常见的设计模式: 1. 工厂模式:JUnit通过TestSuite类实现了工厂模式,它可以根据测试类动态创建测试集合。这使得用户可以方便地组合不同的测试类进行批量执行。 2. 单例模式:JUnit的Test...

    JUnit的框架设计及其使用的设计模式

    这个框架的设计基于一系列高效的设计模式,这些模式不仅提升了JUnit的灵活性,还使得开发者能够方便地扩展和定制测试功能。 首先,JUnit的核心设计理念是“简单易用”。它遵循了“最小化API”原则,提供了一套简洁...

    junit源码以及牵涉到的设计模式

    #### 二、JUnit中的设计模式概述 ##### 1. Command 模式 在JUnit中,`TestCase`类扮演了命令角色,即一个具体的命令对象。这种模式允许程序员将“请求”封装成对象,从而使程序员可以用不同的请求对客户进行参数化...

    使用JUNIT框架实现的设计模式验证演示代码

    JUNIT作为Java编程语言中最广泛使用的单元测试框架,能够帮助开发者验证代码的正确性和设计模式的有效应用。本篇将详细介绍如何使用JUNIT来验证设计模式。 一、设计模式与JUNIT结合的重要性 设计模式的引入是为了...

    Junit所使用的设计模式.doc

    《JUnit 所使用的设计模式》 设计模式是软件开发中的一种通用解决方案,它在特定上下文中解决了常见问题,提高了代码的可读性、可维护性和复用性。JUnit,作为Java编程语言中广泛使用的单元测试框架,巧妙地运用了...

    Java设计模式03设计模式概述.pdf

    这种模式不仅仅局限于设计模式,还包含了架构模式、分析模式和过程模式等。软件模式的基本结构由四个关键部分组成: 1. **问题描述**:明确指出模式所解决的问题是什么。 2. **前提条件**:描述模式适用的环境或...

    设计模式之装饰模式.docx

    设计模式之装饰模式 装饰模式(Decorator Pattern)是一种结构型设计模式,用于动态地给一个对象添加一些额外的职责。该模式允许在不修改原有对象的情况下,动态地改变对象的行为。 定义与结构 装饰模式由四个...

    设计模式面试题

    #### 二、Java中常用设计模式的应用实例 **2. 说出在标准JDK中使用的一些设计模式。** - **装饰器模式**:在Java I/O库中,如`BufferedReader`和`BufferedWriter`。 - **单例模式**:`java.util.Calendar`类中的...

    junit-4.8.2.jar包

    JUnit还提供了测试套件(Test Suites)的概念,这基于组合模式,允许将多个测试类组织在一起,作为一个整体运行。这对于批量执行相关测试非常方便。 在异常处理方面,JUnit使用了模板方法模式,定义了一个测试的...

    STA2JUnit Framework

    Erich Gamma则是《设计模式:可复用面向对象软件的基础》一书的主要作者之一,对软件设计模式的推广有重要贡献。 JUnit 在软件测试社区中备受推崇,曾获得JavaWorld编辑选择奖,被评为最佳Java性能监控/测试工具。...

    junit-4.8.zip

    通过分析JUnit 4.8的源代码,开发者可以深入了解其内部实现,学习如何使用设计模式来构建可扩展、可维护的框架。例如,观察者模式(Observer Pattern)在测试监听器中的应用,工厂模式(Factory Pattern)在创建测试...

    Junit-3.8.1 src

    学习`Junit-3.8.1`源码有助于理解测试框架的设计模式,比如观察者模式、工厂模式等,同时也为过渡到更现代的JUnit版本提供了基础。尽管JUnit 3.8.1已经比较老旧,但它仍然是理解测试基础和测试驱动开发的一个良好...

    junit4.4的最新版本

    JUnit 4.4的API设计得非常开放,允许第三方库扩展其功能,例如Mockito用于模拟对象,PowerMock用于模拟静态方法和构造函数。 9. **更好的错误报告**: 提供了更详细的错误信息和堆栈跟踪,帮助开发者快速定位问题...

    junit4.7.0_中文

    JUnit是一个开源的测试框架,它遵循xUnit测试模式,支持编写和执行针对Java类的方法级别的测试。在JUnit 4.7.0版本中,引入了许多新特性,如注解(Annotations)、测试套件(Test Suites)和参数化测试...

    Junit4.12完整版

    10. **可扩展性**:JUnit 4.12的设计允许开发者通过扩展其核心功能,如创建自定义测试注解、规则或监听器,来适应各种测试场景。 在实际开发中,JUnit 4.12是确保代码质量、提升软件可靠性的得力工具。结合持续集成...

Global site tag (gtag.js) - Google Analytics