From Eclipse I can easily run all the JUnit tests in my application.
通过Eclipse,我可以轻松地在我的应用程序中运行所有的JUnit测试。
I would like to be able to run the tests on target systems from the application jar, without Eclipse (or Ant or Maven or any other development tool).
我希望能够在没有Eclipse(或Ant或Maven或任何其他开发工具)的情况下,从应用程序jar运行目标系统上的测试。
I can see how to run a specific test or suite from the command line.
我可以看到如何从命令行运行特定的测试或套件。
I could manually create a suite listing all the tests in my application, but that seems error prone - I'm sure at some point I'll create a test and forget to add it to the suite.
我可以在我的应用程序中手动创建一个包含所有测试的套件,但这看起来很容易出错——我确信在某个时候我会创建一个测试,并忘记将它添加到套件中。
The Eclipse JUnit plugin has a wizard to create a test suite, but for some reason it doesn't "see" my test classes. It may be looking for JUnit 3 tests, not JUnit 4 annotated tests.
Eclipse JUnit插件有一个创建测试套件的向导,但是出于某种原因它没有“看到”我的测试类。它可能在寻找JUnit 3测试,而不是JUnit 4注释测试。
I could write a tool that would automatically create the suite by scanning the source files.
我可以编写一个工具,通过扫描源文件自动创建套件。
Or I could write code so the application would scan it's own jar file for tests (either by naming convention or by looking for the @Test annotation).
或者我可以编写代码,这样应用程序就可以扫描它自己的jar文件进行测试(通过命名约定或者寻找@Test注释)。
It seems like there should be an easier way. What am I missing?
似乎应该有一个更简单的方法。我缺少什么?
7 个解决方案
#1
6
According to a recent thread on the JUnit mailing list, ClasspathSuite can collect and run all JUnit tests on the classpath. It is not precisely what you want, since it is a class-level annotation, but the source is available, so you may be able to extend its internal discovery mechanism.
根据JUnit邮件列表中最近的一个线程,ClasspathSuite可以在类路径上收集并运行所有JUnit测试。这并不是您想要的,因为它是一个类级别的注释,但是源代码是可用的,所以您可以扩展它的内部发现机制。
#2
5
I ran into a minor problem with my last solution. If I ran "all tests" from Eclipse they ran twice because they ran the individual tests AND the suite. I could have worked around that, but then I realized there was a simpler solution:
我的上一个解决方案遇到了一个小问题。如果我从Eclipse运行“所有测试”,它们会运行两次,因为它们运行单个测试和套件。我本可以解决这个问题,但后来我意识到有一个更简单的解决办法:
package suneido;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class RunAllTests {
public static void run(String jarfile) {
String[] tests = findTests(jarfile);
org.junit.runner.JUnitCore.main(tests);
}
private static String[] findTests(String jarfile) {
ArrayList<String> tests = new ArrayList<String>();
try {
JarFile jf = new JarFile(jarfile);
for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements();) {
String name = e.nextElement().getName();
if (name.startsWith("suneido/") && name.endsWith("Test.class")
&& !name.contains("$"))
tests.add(name.replaceAll("/", ".")
.substring(0, name.length() - 6));
}
jf.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return tests.toArray(new String[0]);
}
public static void main(String[] args) {
run("jsuneido.jar");
}
}
#3
4
Based on http://burtbeckwith.com/blog/?p=52 I came up with the following. It seems to work well.
基于http://burtbeckwith.com/blog/?p=52我得出了下面的结论。看起来效果不错。
I can run it from within my code with:
我可以从我的代码中运行它:
org.junit.runner.JUnitCore.main("suneido.AllTestsSuite");
One weak point is that it relies on a naming convention ("Test" suffix) to identify tests. Another weak point is that the name of the jar file is hard coded.
一个缺点是它依赖命名约定(“Test”后缀)来识别测试。另一个弱点是jar文件的名称是硬编码的。
package suneido;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
/**
* Discovers all JUnit tests in a jar file and runs them in a suite.
*/
@RunWith(AllTestsSuite.AllTestsRunner.class)
public final class AllTestsSuite {
private final static String JARFILE = "jsuneido.jar";
private AllTestsSuite() {
}
public static class AllTestsRunner extends Suite {
public AllTestsRunner(final Class<?> clazz) throws InitializationError {
super(clazz, findClasses());
}
private static Class<?>[] findClasses() {
List<String> classFiles = new ArrayList<String>();
findClasses(classFiles);
List<Class<?>> classes = convertToClasses(classFiles);
return classes.toArray(new Class[classes.size()]);
}
private static void findClasses(final List<String> classFiles) {
JarFile jf;
try {
jf = new JarFile(JARFILE);
for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements();) {
String name = e.nextElement().getName();
if (name.startsWith("suneido/") && name.endsWith("Test.class")
&& !name.contains("$"))
classFiles.add(name.replaceAll("/", ".")
.substring(0, name.length() - 6));
}
jf.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static List<Class<?>> convertToClasses(
final List<String> classFiles) {
List<Class<?>> classes = new ArrayList<Class<?>>();
for (String name : classFiles) {
Class<?> c;
try {
c = Class.forName(name);
}
catch (ClassNotFoundException e) {
throw new AssertionError(e);
}
if (!Modifier.isAbstract(c.getModifiers())) {
classes.add(c);
}
}
return classes;
}
}
}
#4
1
using Class JUnitCore
使用类JUnitCore
JUnitCore is a facade for running tests. It supports running JUnit 4 tests, JUnit 3.8.x tests, and mixtures. To run tests from the command line, run java org.junit.runner.JUnitCore TestClass1 TestClass2 .... For one-shot test runs, use the static method runClasses(Class[]). If you want to add special listeners, create an instance of JUnitCore first and use it to run the tests.
JUnitCore是一个用于运行测试的外观。它支持运行JUnit 4测试,JUnit 3.8。x测试,混合物。要从命令行运行测试,运行java发生TestClass1 TestClass2 ....对于一次性的测试运行,使用静态方法runclass (Class[])。如果您想添加特殊的侦听器,请首先创建JUnitCore的一个实例,并使用它运行测试。
#5
1
I have not tried this as of yet, but came across this blog recently: http://burtbeckwith.com/blog/?p=52
到目前为止我还没有尝试过这个,但是最近我看到了这个博客:http://burtbeckwith.com/blog/?
The author provides a class that discovers all your junits and runs them, so if you slot this in to your project it may provide the capability required?
作者提供了一个类,该类可以发现所有junits并运行它们,所以如果您将其放入项目中,它可能提供所需的功能?
Hope this helps.
希望这个有帮助。
#6
1
Get the Java project and pass the project
获取Java项目并通过该项目
JUnitLaunchShortcut jUnitLaunchShortcut = new JUnitLaunchShortcut();
jUnitLaunchShortcut.launch("Pass the Java Project containing JUnits Classes", "run");
#7
0
You also could use ANT which has built-in task. Write ANT script and run it on target machine. ANT could create report as result.
您还可以使用具有内置任务的ANT。编写ANT脚本并在目标机器上运行它。ANT可以创建报告。
#1
6
According to a recent thread on the JUnit mailing list, ClasspathSuite can collect and run all JUnit tests on the classpath. It is not precisely what you want, since it is a class-level annotation, but the source is available, so you may be able to extend its internal discovery mechanism.
根据JUnit邮件列表中最近的一个线程,ClasspathSuite可以在类路径上收集并运行所有JUnit测试。这并不是您想要的,因为它是一个类级别的注释,但是源代码是可用的,所以您可以扩展它的内部发现机制。
#2
5
I ran into a minor problem with my last solution. If I ran "all tests" from Eclipse they ran twice because they ran the individual tests AND the suite. I could have worked around that, but then I realized there was a simpler solution:
我的上一个解决方案遇到了一个小问题。如果我从Eclipse运行“所有测试”,它们会运行两次,因为它们运行单个测试和套件。我本可以解决这个问题,但后来我意识到有一个更简单的解决办法:
package suneido;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class RunAllTests {
public static void run(String jarfile) {
String[] tests = findTests(jarfile);
org.junit.runner.JUnitCore.main(tests);
}
private static String[] findTests(String jarfile) {
ArrayList<String> tests = new ArrayList<String>();
try {
JarFile jf = new JarFile(jarfile);
for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements();) {
String name = e.nextElement().getName();
if (name.startsWith("suneido/") && name.endsWith("Test.class")
&& !name.contains("$"))
tests.add(name.replaceAll("/", ".")
.substring(0, name.length() - 6));
}
jf.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return tests.toArray(new String[0]);
}
public static void main(String[] args) {
run("jsuneido.jar");
}
}
#3
4
Based on http://burtbeckwith.com/blog/?p=52 I came up with the following. It seems to work well.
基于http://burtbeckwith.com/blog/?p=52我得出了下面的结论。看起来效果不错。
I can run it from within my code with:
我可以从我的代码中运行它:
org.junit.runner.JUnitCore.main("suneido.AllTestsSuite");
One weak point is that it relies on a naming convention ("Test" suffix) to identify tests. Another weak point is that the name of the jar file is hard coded.
一个缺点是它依赖命名约定(“Test”后缀)来识别测试。另一个弱点是jar文件的名称是硬编码的。
package suneido;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
/**
* Discovers all JUnit tests in a jar file and runs them in a suite.
*/
@RunWith(AllTestsSuite.AllTestsRunner.class)
public final class AllTestsSuite {
private final static String JARFILE = "jsuneido.jar";
private AllTestsSuite() {
}
public static class AllTestsRunner extends Suite {
public AllTestsRunner(final Class<?> clazz) throws InitializationError {
super(clazz, findClasses());
}
private static Class<?>[] findClasses() {
List<String> classFiles = new ArrayList<String>();
findClasses(classFiles);
List<Class<?>> classes = convertToClasses(classFiles);
return classes.toArray(new Class[classes.size()]);
}
private static void findClasses(final List<String> classFiles) {
JarFile jf;
try {
jf = new JarFile(JARFILE);
for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements();) {
String name = e.nextElement().getName();
if (name.startsWith("suneido/") && name.endsWith("Test.class")
&& !name.contains("$"))
classFiles.add(name.replaceAll("/", ".")
.substring(0, name.length() - 6));
}
jf.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static List<Class<?>> convertToClasses(
final List<String> classFiles) {
List<Class<?>> classes = new ArrayList<Class<?>>();
for (String name : classFiles) {
Class<?> c;
try {
c = Class.forName(name);
}
catch (ClassNotFoundException e) {
throw new AssertionError(e);
}
if (!Modifier.isAbstract(c.getModifiers())) {
classes.add(c);
}
}
return classes;
}
}
}
#4
1
using Class JUnitCore
使用类JUnitCore
JUnitCore is a facade for running tests. It supports running JUnit 4 tests, JUnit 3.8.x tests, and mixtures. To run tests from the command line, run java org.junit.runner.JUnitCore TestClass1 TestClass2 .... For one-shot test runs, use the static method runClasses(Class[]). If you want to add special listeners, create an instance of JUnitCore first and use it to run the tests.
JUnitCore是一个用于运行测试的外观。它支持运行JUnit 4测试,JUnit 3.8。x测试,混合物。要从命令行运行测试,运行java发生TestClass1 TestClass2 ....对于一次性的测试运行,使用静态方法runclass (Class[])。如果您想添加特殊的侦听器,请首先创建JUnitCore的一个实例,并使用它运行测试。
#5
1
I have not tried this as of yet, but came across this blog recently: http://burtbeckwith.com/blog/?p=52
到目前为止我还没有尝试过这个,但是最近我看到了这个博客:http://burtbeckwith.com/blog/?
The author provides a class that discovers all your junits and runs them, so if you slot this in to your project it may provide the capability required?
作者提供了一个类,该类可以发现所有junits并运行它们,所以如果您将其放入项目中,它可能提供所需的功能?
Hope this helps.
希望这个有帮助。
#6
1
Get the Java project and pass the project
获取Java项目并通过该项目
JUnitLaunchShortcut jUnitLaunchShortcut = new JUnitLaunchShortcut();
jUnitLaunchShortcut.launch("Pass the Java Project containing JUnits Classes", "run");
#7
0
You also could use ANT which has built-in task. Write ANT script and run it on target machine. ANT could create report as result.
您还可以使用具有内置任务的ANT。编写ANT脚本并在目标机器上运行它。ANT可以创建报告。