使用注释在Java上设置测试参数

使用注释在Java上设置测试参数,java,annotations,junit4,Java,Annotations,Junit4,我首先要说的是,我对Java真正不了解的一件事是注释 我来自python背景,因此我倾向于将注释视为方法上的修饰符,这些方法可能做任何事情(比如python上的修饰符) 现在,我有一个问题,在语法方面,如果可以使用注释来解决,看起来会很好,但我不知道是否可以做到 基本上,我有不同版本的API:v1、v2、v3、v4。我对每个版本都进行了JUnit4测试 ApiV1Test.java @Test public void featureX() { Connection conn = new Ap

我首先要说的是,我对Java真正不了解的一件事是注释

我来自python背景,因此我倾向于将注释视为方法上的修饰符,这些方法可能做任何事情(比如python上的修饰符)

现在,我有一个问题,在语法方面,如果可以使用注释来解决,看起来会很好,但我不知道是否可以做到

基本上,我有不同版本的API:v1、v2、v3、v4。我对每个版本都进行了JUnit4测试

ApiV1Test.java

@Test
public void featureX() {
  Connection conn = new ApiConnection("v1");
  response = conn.request("x", "foo")';
  assertEquals("bar", response);
}

@Test
public void featureY() {
  Connection conn = new ApiConnection("v1");
  response = conn.request("y", "foo_y")';
  assertEquals("bar_y", response);
}
ApiV2Test.java

@Test
public void featureX() {
  Connection conn = new ApiConnection("v2");
  response = conn.request("x", "foo")';
  assertEquals("bar", response);
}

@Test
public void featureZ() {
  Connection conn = new ApiConnection("v2");
  response = conn.request("z", "foo_y")';
  assertEquals("bar_z", response);
}
问题是不同的版本有不同的特点;v1可能有功能X和Y,v2可能有功能X和Z。以此类推,每个功能在API的某些子集中可用

因此,这会导致大量代码重复。我只希望有一个具有所有不同功能的文件,并有一个机制来表示“为这些版本运行此测试”,类似于:

@Test
@Versions("v1", "v2")
public void featureX(String version) {
  Connection conn = new ApiConnection(version);
  response = conn.request("x", "foo")';
  assertEquals("bar", response);
}

@Test
@Versions("v1")
public void featureY(String version) {
  Connection conn = new ApiConnection(version);
  response = conn.request("y", "foo_y")';
  assertEquals("bar_y", response);
}


@Test
@Versions("v2")
public void featureZ(String version) {
  Connection conn = new ApiConnection(version);
  response = conn.request("z", "foo_z")';
  assertEquals("bar_z", response);
}

这可能吗?

从JUnit4开始,您就可以这样做了。查找
类别

// In Version1.java.
public interface Version1 { /* category marker */ }

// In Version2.java.
public interface Version2 { /* category marker */ }

// Part of ApiV1Test.java
@Test
@Category({Version1.class, Version2.class})
public void featureX( String version) {
    Connection conn = new ApiConnection(version);
    response = conn.request("x", "foo")';
    assertEquals("bar", response);
}

// Part of ApiV2Test.java
@Test
@Category(Version2.class)
public void featureZ(String version) {
    Connection conn = new ApiConnection(version);
    response = conn.request("z", "foo_z")';
    assertEquals("bar_z", response);
}

//Part of V1TestSuite.java, chosen through an Ant target or Maven execution.
@RunWith(Categories.class)
@IncludeCategory(Version1.class)
@SuiteClasses(ApiV1Test.class, ApiV2Test.class)  // *
public class V1TestSuite {}
您可以根据需要将测试方法拆分为尽可能少或尽可能多的类。只需编辑标有星号的线。然后,手动运行
V1TestSuite
,或者使用适当的方法让Ant目标或Maven执行测试步骤运行它

蚂蚁


我对那个代码片段有点困惑
featureX
是哪个类的一部分?我猜它在哪里说
@Versions(“v2”)
它应该说
@Category({Version2.class})
。这看起来很棒,但我不明白的是
字符串版本
参数的值从何而来。剪切粘贴错误。很抱歉我将再次编辑。在
@Category(Version1.class)
中,不需要字符串参数。
@IncludeCategory(Version1.class)
告诉JUnit只运行标记有该类别的方法作为测试套件的一部分。但是
ApiConnection
的构造函数将获得什么值作为参数?这就是我需要设置正在测试的API的地方。哦,天哪。测试方法不应该在JUnit代码中使用参数。您可以使用参数化的
@测试,并让测试类的构造函数获取一系列参数;然后该方法可以使用
此.version
。当版本错误时,可以使用
关闭测试。
<target name="text-version1" depends="compile-tests">
    <junit printsummary="yes" haltonfailure="yes">
        <classpath>
            <pathelement location="${build.tests}"/>
            <pathelement path="${java.class.path}"/>
        </classpath>

        <formatter type="plain"/>

        <test name="my.test.V1TestSuite"/>
    </junit>
</target>