`
Tin
  • 浏览: 138573 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

在JUnit中多个testCase只执行一次setup和tearDown的方法

阅读更多
这个问题出现在这种情况,你的每个testCase都需要使用某一种初始化比较耗时的对象(资源),举例如数据库连接、Spring Context。我们遇到的问题是Selenium测试中开启和关闭浏览器,如果一个test启动关闭(我们的程序还需要登录和注销),这样测试的时间会拖的很长,给持续集成带来了困难。
所以,我们需要在每组不会冲突的test中间共享一个浏览器窗口,这样也就需要一个全局的setUp和tearDown。问题是JUnit 3.8.1里面的setUp和tearDown是在每个test之前和之后运行的,如果在里面初始化和关闭浏览器就会造成上面所说的问题。要解决它,就产生了如下3种思路:
1、升级,使用JUnit4
JUnit4从TestNG里面吸取了两个注释:@BeforeClass和@AfterClass
用它们注释过的方法就会只初始化一次,完全符合我们的需求。
public class SeleniumTestCase extends SeleneseTestCase4 {

    
protected static final Log log = LogFactory.getLog(SeleniumTestCase.class);
    
protected static Selenium selenium = null;

    
/** *//**
     * 包含了登录的代码,保证在一个测试内部只执行一次开启浏览器并登录操作
     * 
@throws Exception
     
*/

    @BeforeClass
    
public static void startSelenium() throws Exception {
        log.debug(
"Starting Selenium");
        selenium 
= SeleniumSession.getCurrentSession().getSelenium();
    }


    
/** *//**
     * 在该类包含的所有测试结束之后关闭浏览器
     * 
@throws Exception
     
*/

    @AfterClass
    
public static void stopSelenium() throws Exception {
        log.debug(
"Stoping Selenium");
        selenium.stop();
    }

}
这个里面的selenium = SeleniumSession.getCurrentSession().getSelenium();其实是个singleton,第一次open new,后来就直接返回selenium的instance(具体参考其它文章)。
这样做非常舒服,因为完全不是Trick,而是新的feature,用起来踏实。这样,这个类的所有@Test就会公用一个selenium打开的浏览器了。
那么缺点是什么呢?缺点是放到CI环境的时候如果使用我们习惯的Ant写执行脚本的话必须将Ant升级到1.7Beta3,因为Ant 1.6.5的Junit task不支持JUnit4……当然升级并不会带来代码的变化,但是问题在于Ant 1.7还是Beta,而且JUnit4需要JDK5的Annotation,你的PM估计要撇嘴了

2、JVM级别钩子法
因为JVM支持关闭时执行制定代码的钩子,而static代码会在类初始化时执行,再加上Ant调用的是类似命令行的java命令,实际上每一个测试运行在一个完整的JVM启动关闭周期里面,所以也就产生了这种解决方案。
这个方案来自taowen同学的两则Selenium经验
代码我恢复了一下,大概是这样:
public abstract class SomeTestCase extends TestCase {

  
static {
    
// perform the "global" set up logic
    
//这里的代码会在类初始化时执行,所以相当于BeforeClass
    log.debug("Starting Selenium");
        selenium 
= SeleniumSession.getCurrentSession().getSelenium();

    
// and now register the shutdown hook for tear down logic
    
//将一个匿名方法写到这里,就相当于AfterClass
    Runtime.getRuntime().addShutdownHook(
      
new Thread(){
          
public void run() {
             log.debug(
"Stoping Selenium");
             selenium.stop();
           }
       }
     );
  }

}

这个方法挺酷的,我认为完全可以被称作“奇技淫巧”。缺点就是,有点不好看。

3、还有别的方法,这个来自Selenium网站,似乎是不错的中庸方案。
import junit.framework.*;
import junit.extensions.TestSetup;

public class AllTestsOneTimeSetup {

    
public static Test suite() {

        TestSuite suite 
= new TestSuite();

        suite.addTest(SomeTest.suite());
        suite.addTest(AnotherTest.suite());

        TestSetup wrapper 
= new TestSetup(suite) {

            
protected void setUp() {
                oneTimeSetUp();
            }

            
protected void tearDown() {
                oneTimeTearDown();
            }
        };

        
return wrapper;
    }

    
public static void oneTimeSetUp() {
        
// one-time initialization code
    }

    
public static void oneTimeTearDown() {
        
// one-time cleanup code
    }
}


这个好像是比较正统的方案,不好意思我并没有试验,但是看起来这的确可能是限定用JDK 1.4或JUnit 3.8.1的最佳解决方案。欢迎尝试。相关的连接参考这里:http://www.cs.wm.edu/~noonan/junit/doc/faq/faq.htm#organize_3 

分享到:
评论

相关推荐

    在eclipse中使用junit4教程

    jUnit4 在 Eclipse 中的使用教程 jUnit4 是 JUnit 框架有史以来的最大改进,其主要...jUnit4 是一个功能强大且灵活的测试框架,在 Eclipse 中使用 jUnit4 可以方便地进行单元测试和集成测试,提高测试效率和测试质量。

    JUnit3.8.1 以及使用JUnit测试的代码demo

    在`JUnit & 简单Junit使用代码`这个文件中,可能包含了一个或多个示例,展示了如何创建测试类、编写测试方法、使用断言以及设置测试环境。例如,可能有一个简单的数学操作类`MathUtils`,以及对应的测试类`...

    JUnit的学习和经验分享

    setUp和tearDown是JUnit framework中的两个重要函数。setUp在每个测试方法调用前被调用,负责初始化测试方法所需要的测试环境;tearDown在每个测试方法被调用之后被调用,负责撤销测试环境。 组装TestSuite 在...

    JUnit是一个开发源代码的Java测试框架

    `setUp`和`tearDown`方法在早期版本中起到相同作用。 - **测试套件(Test Suites)**:测试套件允许组织和组合多个测试类或测试方法,方便批量执行。这在处理大型项目时尤其有用。 - **测试运行器**:JUnit ...

    junit3.8 和junit4 api

    在JUnit 3中,初始化和清理工作是通过`setUp()`和`tearDown()`方法实现的,它们会在每个测试方法之前和之后自动调用。 4. **测试套件(Test Suites)**:通过`@Suite`注解创建,但这是JUnit 4的特性。在JUnit 3中,...

    Junit4教程

    下面我们将详细介绍Junit4的使用和在Eclipse中如何高效方便的进行对代码进行测试。 Junit4概述 JUnit4是JUnit框架有史以来的最大改进,其主要目标便是利用Java5的Annotation特性简化测试用例的编写。Annotation是...

    Junit简介和扩展

    JUnit是一个广泛使用的Java单元测试框架,由Kent Beck和Erich Gamma创建。自成立以来,JUnit已经成为xUnit家族中最成功的一员,该家族源自Kent Beck开发的sUnit。JUnit主要用于程序员进行白盒测试,即通过对程序内部...

    eclipse中使用junit4

    在JUnit4中,我们使用`@Before`和`@After`注解来定义在每个测试方法之前和之后执行的方法,分别替代了JUnit3中的`setUp`和`tearDown`。而测试方法则使用`@Test`注解标识。这种方式更加灵活,使得测试代码更清晰,也...

    junit4学习文档

    在 JUnit3 中,使用 `setUp` 和 `tearDown` 方法来进行测试前后的初始化和清理工作。而在 JUnit4 中,使用 `@Before` 和 `@After` 注解替代了这些方法。 #### 四、JUnit4 实践案例 下面是一个使用 JUnit4 编写的...

    JUnit和设计模式.ppt

    例如,在一个简单的数学测试案例中,我们可能会创建两个double类型的变量,然后在setUp()方法中设置它们的值,接着编写具体的测试方法,如testAdd(),在这个方法中进行预期结果的验证。 运行JUnit测试有多种方式,...

    junit学习文档

    `@Before`和`@After`注解与JUnit 3中的`setUp()`和`tearDown()`类似,但它们是针对每个测试方法的,每次执行测试方法前都会调用`@Before`注解的方法,测试方法执行后调用`@After`注解的方法。 JUnit 4还支持使用`@...

    Junit单元测试内部机制解析

    - **TestCase**:这是最基本的测试单元,包含一个或多个测试方法,通常一个`TestCase`对应于一个具体的业务功能。 ##### 3. **测试执行的关键方法** - `runBare()`:这是`TestCase`的核心执行方法,负责实际的测试...

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

    例如,在JUnit中,`run`方法可以被看作是一个命令,它负责执行一个测试案例,而不需要关心具体的测试结果如何处理。 ##### 2. Composite 模式 Composite模式(组合模式)用于构建树形结构,以便表示“部分-整体”...

    1小时学会JUnit4,学不会找我

    这里,`@Before`和`@After`注解分别替代了JUnit3中的`setUp`和`tearDown`方法,它们会在每个测试方法执行前和执行后运行,用于准备测试环境和清理工作。 JUnit4还提供了一些其他有用的注解,例如: - `@BeforeClass...

    JUNit教程:JUNit基本教程

    在这个示例中,我们定义了一个名为 `TestSample` 的测试类,其中包含了初始化 (`setUp`)、测试方法 (`testMethod1`) 和清理 (`tearDown`) 方法。 #### 八、总结 JUnit 是 Java 开发者进行单元测试的重要工具,它...

    Junit学习资料

    5. `tearDown()`方法在每个测试方法执行后被调用,用于清理测试过程中产生的临时资源,但在这个例子中没有进行实质性的清理操作。 6. `testBodyStatus()`和`testBodySame()`是两个测试方法,分别包含了不同的断言。...

    junit3.8.1 api. zip

    `TestCase`提供了一些基础方法,如`setUp()`和`tearDown()`,分别用于在测试开始前和结束后执行的初始化和清理工作。 - `@Test`: 这个注解标记在测试方法上,告诉Junit这是一个需要运行的测试。在Junit 3中,测试...

Global site tag (gtag.js) - Google Analytics