簡體   English   中英

如何在Java應用程序中以編程方式運行所有JUnit測試?

[英]How do I programmatically run all the JUnit tests in my Java application?

從Eclipse我可以輕松地在我的應用程序中運行所有JUnit測試。

我希望能夠在沒有Eclipse(或Ant或Maven或任何其他開發工具)的情況下從應用程序jar運行目標系統上的測試。

我可以看到如何從命令行運行特定的測試或套件。

我可以手動創建一個列出我的應用程序中的所有測試的套件,但這似乎容易出錯 - 我確信在某些時候我會創建一個測試而忘記將它添加到套件中。

Eclipse JUnit插件有一個創建測試套件的向導,但由於某種原因,它沒有“看到”我的測試類。 它可能正在尋找JUnit 3測試,而不是JUnit 4注釋測試。

我可以編寫一個工具,通過掃描源文件自動創建套件。

或者我可以編寫代碼,以便應用程序掃描它自己的jar文件進行測試(通過命名約定或查找@Test注釋)。

似乎應該有一個更簡單的方法。 我錯過了什么?

根據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;
        }
    }

}

我還沒有嘗試過這個,但最近遇到了這個博客: 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可以創建報告作為結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM