简体   繁体   English

通过指向外部jar以编程方式运行testNG会引发ClassNotFoundException

[英]Running testNG programmatically by pointing to an external jar throws ClassNotFoundException

I want to run TestNG tests programmatically by pointing to a jar which contains the test classes. 我想通过指向包含测试类的jar来以编程方式运行TestNG测试。 For this, firstly the testng.xml is parsed and the classes are taken. 为此,首先解析testng.xml并获取类。 Then each class is loaded into the classpath using the URLCLassLoader . 然后,使用URLCLassLoader将每个类加载到类路径中。 But this throws org.testng.TestNGException: Cannot find class in classpath: exception. 但这会引发org.testng.TestNGException: Cannot find class in classpath:异常中org.testng.TestNGException: Cannot find class in classpath:

Below is the code I tried 下面是我尝试的代码

public void execute() {
    String testNGXmlPath = "/path/to/testng.xml";
    try {
        getClassesToLoad(testNGXmlPath);
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    }
    TestNG testng = new TestNG();
    List<String> suites = Lists.newArrayList();
    suites.add(testNGXmlPath);
    testng.setTestSuites(suites);
    testng.run();
}

public void getClassesToLoad(String path) throws ParserConfigurationException, IOException, SAXException {
    File inputFile = new File(path);
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(inputFile);
    doc.getDocumentElement().normalize();
    NodeList nodeList = doc.getElementsByTagName("class");
    Element element;
    Node node;
    NamedNodeMap namedNodeMap;

    int i, length;
    length = nodeList.getLength();
    for (int j=0; j < length; j++) {
        element = (Element)nodeList.item(j);
        namedNodeMap = element.getAttributes();
        if (namedNodeMap != null) {
            for (i=0; i<namedNodeMap.getLength(); i++) {
                node = namedNodeMap.item(i);
                if (node.getNodeName() == "name") {
                    try {
                        loadClass("/path/to/testng.sample-1.0-SNAPSHOT.jar", node.getNodeValue());
                    } catch (ClassNotFoundException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        }
    }
}

public static void loadClass(String jarFilePath, String className) throws MalformedURLException,
        ClassNotFoundException {
    File jarFile  = new File(jarFilePath);
    if (jarFile.isFile()) {
        URL url = jarFile.toURL();
        URL[] urls = new URL[] { url };
        ClassLoader cl = new URLClassLoader(urls);
        cl.loadClass(className);
    }
}

You are loading the class loader using the URLClassLoader, but for the classes that were loaded by your class loader to be visible to the current ContextualClassLoader, you need to set it up. 您正在使用URLClassLoader加载类加载器,但是要使您的类加载器加载的类对当前ContextualClassLoader可见,您需要对其进行设置。

Please try doing it via Thread.currentThread().setContextClassLoader(); 请尝试通过Thread.currentThread().setContextClassLoader(); within your loadClass() method and then try running your test. loadClass()方法中,然后尝试运行测试。 This would ensure that when TestNG kicks in, it uses the ContextClassLoader that you injected to the current thread, to be used to load classes and thus help you get past your ClassNotFoundException 这样可以确保当TestNG启动时,它将使用您注入到当前线程中的ContextClassLoader来加载类,从而帮助您克服ClassNotFoundException

If your intention is to run your tests from a jar, you can simply package them and run using your xml. 如果您打算从jar运行测试,则可以简单地打包它们并使用xml运行。
Refer to the commandline section of the testng documentation . 请参阅testng 文档的命令行部分。

Can refer to these steps if yours is a maven project : 如果您是Maven项目,可以参考以下步骤

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM