我想在(restful)webservice上做一些功能测试。 testsuite包含一堆测试用例,每个测试用例在Web服务上执行几个HTTP请求。
当然,Web服务必须运行或测试失败。 : - )
启动webservice需要几分钟(它会提升一些重量级数据),所以我想尽可能少地启动它(至少所有只有来自服务的GET资源可以共享一个的测试用例)。
在测试运行之前,有没有办法在测试套件中设置炸弹,就像测试用例的@BeforeClass方法一样?
答案 0 :(得分:22)
现在的答案是在您的套件中创建@ClassRule
。将在运行每个测试类之前或之后(取决于您如何实现它)调用该规则。您可以扩展/实现几个不同的基类。类规则的好处是,如果你不将它们实现为匿名类,那么你可以重用代码!
以下是关于它们的文章:http://java.dzone.com/articles/junit-49-class-and-suite-level-rules
以下是一些示例代码来说明它们的用法。是的,这是微不足道的,但它应该足以说明你的生命周期,以便你开始。
首先是套件定义:
import org.junit.*;
import org.junit.rules.ExternalResource;
import org.junit.runners.Suite;
import org.junit.runner.RunWith;
@RunWith( Suite.class )
@Suite.SuiteClasses( {
RuleTest.class,
} )
public class RuleSuite{
private static int bCount = 0;
private static int aCount = 0;
@ClassRule
public static ExternalResource testRule = new ExternalResource(){
@Override
protected void before() throws Throwable{
System.err.println( "before test class: " + ++bCount );
sss = "asdf";
};
@Override
protected void after(){
System.err.println( "after test class: " + ++aCount );
};
};
public static String sss;
}
现在测试类定义:
import static org.junit.Assert.*;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExternalResource;
public class RuleTest {
@Test
public void asdf1(){
assertNotNull( "A value should've been set by a rule.", RuleSuite.sss );
}
@Test
public void asdf2(){
assertEquals( "This value should be set by the rule.", "asdf", RuleSuite.sss );
}
}
答案 1 :(得分:1)
jUnit无法做到这一点 - 尽管TestNG确实有@BeforeSuite
和@AfterSuite
注释。通常,您可以使用构建系统来执行此操作。在maven中,有“预集成测试”和“集成后测试”阶段。在ANT中,您只需添加步骤即可完成任务。
你的问题几乎是Before and After Suite execution hook in jUnit 4.x的问题,所以我会看看那边的建议。
答案 2 :(得分:0)
一种选择是使用像Apache Ant这样的东西来启动你的单元测试套件。 然后,您可以在junit目标之前和之后放置目标调用,以启动和停止Web服务:
<target name="start.webservice"><!-- starts the webservice... --></target>
<target name="stop.webservice"><!-- stops the webservice... --></target>
<target name="unit.test"><!-- just runs the tests... --></target>
<target name="run.test.suite"
depends="start.webservice, unit.test, stop.webservice"/>
然后使用ant(或您选择的集成工具)运行您的套件。大多数IDE都具有Ant支持,它使得将测试移动到连续集成环境(其中许多使用Ant目标来定义自己的测试)变得更加容易。
答案 3 :(得分:-2)
顺便说一句,让单元测试实际调用Web服务,数据库等外部资源是个坏主意。
单元测试应该超级快速运行,并且每次运行套件的“几分钟”延迟意味着它不会运行得那么多。
我的建议:
使用EasyMock(http://www.easymock.org/)等单元测试来模拟外部依赖项。
使用Fitnesse(http://fitnesse.org/)或本地解决方案构建一个独立的集成测试套件,该解决方案针对测试环境运行并持续运行。