Как программно запустить все тесты JUnit в моем приложении Java?
из Eclipse, я могу легко запустить все тесты JUnit в моем приложении.
Я хотел бы иметь возможность запускать тесты на целевых системах из jar приложения без Eclipse (или Ant или Maven или любого другого инструмента разработки).
Я вижу, как запустить определенный тест или набор из командной строки.
Я мог бы вручную создать набор, перечисляющий все тесты в моем приложении, но это кажется подверженным ошибкам - я уверен, что в какой-то момент я создам тест и забудь добавить его в номер.
плагин Eclipse JUnit имеет мастер для создания набора тестов, но по какой-то причине он не "видит" мои тестовые классы. Он может искать тесты JUnit 3, а не аннотированные тесты JUnit 4.
Я мог бы написать инструмент, который автоматически создаст пакет путем сканирования исходных файлов.
или я мог бы написать код, чтобы приложение сканировало собственный файл jar для тестов (либо путем соглашения об именах, либо путем поиска @Test комментарий.)
кажется, что там должен быть более простой способ. Что я упускаю?
7 ответов
по данным недавней теме в списке рассылки JUnit,ClasspathSuite может собирать и запускать все тесты JUnit на пути к классам. Это не совсем то, что вы хотите, так как это аннотация уровня класса, но источник доступен, поэтому вы можете расширить его внутренний механизм обнаружения.
я столкнулся с небольшой проблемой с моим последним решением. Если я запускал "все тесты" из 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");
}
}
на основе http://burtbeckwith.com/blog/?p=52 я придумал следующее. Кажется, это работает хорошо.
Я могу запустить его в мой код:
org.junit.runner.JUnitCore.main("suneido.AllTestsSuite");
одним из слабых мест является то, что он полагается на соглашение об именовании (суффикс"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;
}
}
}
использование класса JUnitCore
JUnitCore-это фасад для запуска тестов. Он поддерживает запуск тестов JUnit 4, JUnit 3.8.x тесты и смеси. Чтобы запустить тесты из командной строки, запустите java org.тесты JUnit.бегун.JUnitCore TestClass1 TestClass2 .... Для однократных тестовых запусков используйте статический метод runClasses (Class[]). Если вы хотите добавить специальные прослушиватели, сначала создайте экземпляр JUnitCore и используйте его для запуска тестов.
Я еще не пробовал это, но недавно наткнулся на этот блог: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 может создать отчет в результате.