“ IntegrationTest”で終わるものを除くすべてのJUnit単体テストを実行するにはどうすればよいですか? IntelliJ IDEAプロジェクトで統合テストランナーを使用していますか?
-
05-07-2019 - |
質問
基本的に、JUnitのstatic suite()メソッドを使用して、IntelliJ IDEAプロジェクトのすべてのJUnit unit テストを実行します(JUnit統合テストを除く)。なぜ静的なsuite()メソッドを使用するのですか? IntelliJ IDEAのJUnitテストランナーを使用して、アプリケーションのすべての単体テストを実行できます(また、命名規則によってすべての統合テストを簡単に除外できるため)。これまでのコードは次のようになります。
package com.acme;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class AllUnitTests extends TestCase {
public static Test suite() {
List classes = getUnitTestClasses();
return createTestSuite(classes);
}
private static List getUnitTestClasses() {
List classes = new ArrayList();
classes.add(CalculatorTest.class);
return classes;
}
private static TestSuite createTestSuite(List allClasses) {
TestSuite suite = new TestSuite("All Unit Tests");
for (Iterator i = allClasses.iterator(); i.hasNext();) {
suite.addTestSuite((Class<? extends TestCase>) i.next());
}
return suite;
}
}
クラス名が&quot; IntegrationTest&quot;で終わる場合を除き、メソッドgetUnitTestClasses()を書き換えてTestCaseを拡張するすべてのプロジェクトクラスを追加する必要があります。
たとえばMavenでこれを簡単に行えることはわかっていますが、IntelliJ IDEAで統合テストランナーを使用できるようにする必要があります。緑色のバーが好きです:)
解決
ほとんどの作業を行うためのコードをいくつか作成しました。ファイルがJARではなくローカルディスクにある場合にのみ機能します。必要なのは、パッケージ内の1つのクラスだけです。この目的のために、パッケージを見つけることができるように、Locator.javaクラスを作成できます。
public class ClassEnumerator {
public static void main(String[] args) throws ClassNotFoundException {
List<Class<?>> list = listClassesInSamePackage(Locator.class, true);
System.out.println(list);
}
private static List<Class<?>> listClassesInSamePackage(Class<?> locator, boolean includeLocator)
throws ClassNotFoundException {
File packageFile = getPackageFile(locator);
String ignore = includeLocator ? null : locator.getSimpleName() + ".class";
return toClassList(locator.getPackage().getName(), listClassNames(packageFile, ignore));
}
private static File getPackageFile(Class<?> locator) {
URL url = locator.getClassLoader().getResource(locator.getName().replace(".", "/") + ".class");
if (url == null) {
throw new RuntimeException("Cannot locate " + Locator.class.getName());
}
try {
return new File(url.toURI()).getParentFile();
}
catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
private static String[] listClassNames(File packageFile, final String ignore) {
return packageFile.list(new FilenameFilter(){
@Override
public boolean accept(File dir, String name) {
if (name.equals(ignore)) {
return false;
}
return name.endsWith(".class");
}
});
}
private static List<Class<?>> toClassList(String packageName, String[] classNames)
throws ClassNotFoundException {
List<Class<?>> result = new ArrayList<Class<?>>(classNames.length);
for (String className : classNames) {
// Strip the .class
String simpleName = className.substring(0, className.length() - 6);
result.add(Class.forName(packageName + "." + simpleName));
}
return result;
}
}
他のヒント
junitテストの各主要グループを独自のルートパッケージに入れる方法はどうですか。私は自分のプロジェクトで次のパッケージ構造を使用しています:
test.
quick.
com.acme
slow.
com.acme
コーディングを行わなくても、すべてのテストを実行するようにIntelliJをセットアップできます。すべてのテストを実行します。クイックテストのみ、またはスローテストのみです。
JUnit4とSuite-Runnerの使用はどうですか?
例:
@RunWith(Suite.class)
@Suite.SuiteClasses({
UserUnitTest.class,
AnotherUnitTest.class
})
public class UnitTestSuite {}
すべての単体テストを見つけるために小さなシェルスクリプトを作成し、統合テストを見つけるために別のシェルスクリプトを作成しました。私のブログエントリをご覧ください。 http://blog.timomeinen.de/ 2010/02 / find-all-junit-tests-in-a-project /
Spring TestContextを使用する場合は、@ IfProfileアノテーションを使用してさまざまなテストを宣言できます。
よろしく、 ティモ・マイネン
Springは、PathMatchingResourcePatternResolverに優れたクラスパス検索機能を実装しました。 classpath *:プレフィックスを使用すると、特定の階層内のクラスを含むすべてのリソースを検索し、必要に応じてフィルタリングすることもできます。次に、AbstractTypeHierarchyTraversingFilter、AnnotationTypeFilter、およびAssignableTypeFilterの子を使用して、クラスレベルのアノテーションまたはそれらが実装するインターフェースでこれらのリソースをフィルタリングできます。
解決策: https://github.com/MichaelTamm/junit-toolbox
次の機能を使用します
@RunWith(WildcardPatternSuite.class)
@SuiteClasses({"**/*.class", "!**/*IntegrationTest.class"})
public class AllTestsExceptionIntegrationSuit {
}
統合テストが... IntegrationTestで終わる命名パターンに従っていると仮定し、ファイルを最上位のパッケージに配置します(したがって、** / *。class検索はすべてのテストをピックアップする機会があります)