如何编程方式运行,在我的Java应用程序的所有JUnit测试?
题
在Eclipse中,我可以很容易地在我的应用程序运行所有的JUnit测试。
我想能够从应用程序运行罐子目标系统上的试验中,不使用Eclipse(或Ant或Maven或任何其他开发工具)。
我可以看到如何运行的命令行的特定测试或套件。
我可以手动创建一个套件列出所有的测试中我的应用程序,但似乎容易出错 - 我敢肯定,在某些时候,我会创建一个测试,忘记将它添加到该套件
在Eclipse中的JUnit插件有一个向导来创建一个测试套件,但由于某些原因,它不“看”我的测试类。它可能会寻找JUnit 3次测试,不JUnit 4中标注的测试。
我可以写一个工具,将通过扫描源文件自动创建套件。
或者我可以写代码,因此应用程序将扫描它的测试(通过命名约定或通过寻找@Test标注)自己的jar文件。
好像应该有一个更简单的方法。我缺少什么?
解决方案 2
我遇到了我的最后解决一个小问题。如果我跑,从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");
}
}
其他提示
根据 JUnit的邮件列表中最近的螺纹, ClasspathSuite 可以收集并运行的类路径上的所有JUnit测试。这不正是你想要的东西,因为它是一个类级别的注释,但提供源代码,所以你可能能够延长其内部发现机制。
根据 http://burtbeckwith.com/blog/?p=52 我想出了以下内容。它似乎运作良好。
我可以从我的代码内的运行:
org.junit.runner.JUnitCore.main("suneido.AllTestsSuite");
一个不足之处是它依赖于命名约定(“测试”后缀)来识别测试。另一个不足之处是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;
}
}
}
我还没有试过这个作为然而,但最近遇到这个博客来了:的http:// burtbeckwith.com/blog/?p=52
作者提供了发现你所有的junits和运行它们的一类,因此,如果您插槽此到您的项目中它可以提供所需的能力?
希望这有助于。
获取Java项目,并通过项目
JUnitLaunchShortcut jUnitLaunchShortcut = new JUnitLaunchShortcut();
jUnitLaunchShortcut.launch("Pass the Java Project containing JUnits Classes", "run");
您也可以使用 ANT 它有内置的任务。 编写Ant脚本和目标机器上运行它。 ANT可以创建报告结果。