Компиляция тестового класса TestNG ничем не отличается от компиляции обычного java класса.
Предполагая, что у вас нет проблем с CLASSPATH (приведенный ниже код не учитывает это ), вот простой пример, который вы можете использовать для начала работы.
Ссылка: Большая часть реализации в значительной степени вдохновлена и взята из этого блога .
Предположим, что у вас есть текстовый файл с именем sample.txt
, содержимое которого указано ниже:
package foo.bar;
import org.testng.annotations.Test;
public class Example {
@Test
public void testMethod() {
System.err.println("Hello world");
}
}
import java.nio.file.Path;
public class ClassInfo {
String packageName;
String className;
String sourceCode;
Path javaFile;
Path classFile;
}
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.Collectors;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import org.testng.TestNG;
public class DynamicTestNgExecutor {
public static void main(String[] args) throws Exception {
DynamicTestNgExecutor.runTests("src/test/resources/sample.txt", "foo.bar.Example");
}
public static void runTests(String sourcePath, String className) throws Exception {
ClassInfo classInfo = parse(sourcePath, className);
saveSource(classInfo);
compileSource(classInfo);
runClass(classInfo, className);
}
private static void runClass(ClassInfo classInfo, String className)
throws MalformedURLException, ClassNotFoundException {
URL classUrl = classInfo.javaFile.getParent().toFile().toURI().toURL();
if (!classInfo.packageName.isEmpty()) {
File file = classInfo.javaFile.toFile();
int count = classInfo.packageName.split("\\Q.\\E").length;
for (int i = 0; i <= count; i++) {
file = file.getParentFile();
}
classUrl = file.toURI().toURL();
}
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] {classUrl});
Class<?> clazz = Class.forName(className, true, classLoader);
TestNG testNG = new TestNG();
testNG.setTestClasses(new Class[] {clazz});
testNG.setVerbose(2);
testNG.run();
}
public static ClassInfo parse(String sourcePath, String className) throws FileNotFoundException {
InputStream stream = new FileInputStream(sourcePath);
String separator = System.getProperty("line.separator");
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
ClassInfo info = new ClassInfo();
info.className = className;
info.sourceCode = reader.lines().collect(Collectors.joining(separator));
info.packageName = packageName(info.sourceCode);
return info;
}
private static void compileSource(ClassInfo classInfo) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(System.in, System.out, System.err, classInfo.javaFile.toFile().getAbsolutePath());
classInfo.classFile = classInfo.javaFile.getParent().resolve(classInfo.className + ".class");
}
public static void saveSource(ClassInfo classInfo) throws IOException {
String folder = folderName(classInfo.packageName);
String tmpProperty = System.getProperty("java.io.tmpdir") + File.separator + folder;
final boolean success = new File(tmpProperty).mkdirs();
if (!success) {
throw new IllegalStateException("Encountered problems when creating the package structure " + tmpProperty);
}
classInfo.javaFile = Paths.get(tmpProperty, simpleClassName(classInfo.className) + ".java");
Files.write(classInfo.javaFile, classInfo.sourceCode.getBytes(UTF_8));
}
private static String simpleClassName(String className) {
String[] parts = className.split("\\Q.\\E");
if (parts.length == 1) {
//No package name in the class
return parts[0];
}
int lastButOne = parts.length - 1;
return parts[lastButOne];
}
private static String folderName(String pkg) {
if (pkg.isEmpty()) {
return "";
}
pkg = pkg.replaceAll("\\Q.\\E", "/");
return pkg;
}
private static String packageName(String source) {
String separator = System.getProperty("line.separator");
String pkg =
Arrays.stream(source.split(separator))
.filter(each -> each.contains("package"))
.findAny()
.orElse("");
if (pkg.isEmpty()) {
return "";
}
return pkg.replaceAll("package ", "").replaceAll(";", "");
}
}