Ant是大家熟悉的构建工具,一般情况下,大家都是使用build.xml文件来配置使用Ant,这样的Ant已经是十分强大的。但有些怪异的场景需求特殊,你可能希望在自己的java程序中直接使用Ant已经准备好的功能强大的轮子,比如:在你的web应用中嵌入各种Junit测试,通过Jsp页面控制集成测试,生成测试报告后在web直接展示。你可能可以说,我完全可以通过代码自己实现,生成报告也最多自己在扩展封装下而已。但是Ant已经提供测试,报告各种强大的功能,为何我们不自己使用呢。我们只是不想只在构建的时候做这些事,而是在我们的进程中使用Ant.
令我们高兴的是,Ant是使用Java开发的,对我们,只是引入了几个Ant的jar包就可以使用了。
说到了测试,这次是做一个自动化测试框架,我希望达到上面所说的怪异需求。那我最需要的是什么,是的,通过ant执行junit测试,并按照模板输出测试报告。在参考了Ant的API后,我折腾出了下面这段代码.
//所有的Task都必须设置一个Project对象,可以共用一个Project.
private Project prj = new Project();
public void simpleJunitTest(String testClassName, File reportXmlDir, boolean isFork) throws Exception {
JUnitTask task = new JUnitTask();
initJunitTask(isFork, task);
JUnitTest test = new JUnitTest(testClassName);
task.addTest(test);
test.setTodir(reportXmlDir);
task.execute();
}
public void callBatchJunitTest(String includes, boolean isFork, FileSet fs, File reportXmlDir) throws Exception {
JUnitTask task = new JUnitTask();
initJunitTask(isFork, task);
BatchTest btest = task.createBatchTest();
btest.addFileSet(fs);
btest.setTodir(reportXmlDir);
task.execute();
}
private void initJunitTask(boolean isFork, JUnitTask task) {
task.setProject(prj);
task.setFork(isFork);
JUnitTask.SummaryAttribute printSummary = new JUnitTask.SummaryAttribute();
printSummary.setValue("yes");
task.setPrintsummary(printSummary);
task.setHaltonerror(false);
task.setHaltonfailure(false);
task.setFailureProperty("junit.failure");
task.setErrorProperty("junit.error");
task.addFormatter(createFormatterElement("xml"));
}
private FormatterElement createFormatterElement(String value) {
FormatterElement fe = new FormatterElement();
FormatterElement.TypeAttribute typeAttribute = new FormatterElement.TypeAttribute();
typeAttribute.setValue(value);
fe.setType(typeAttribute);
return fe;
}
public void createJunitReport(File reportXmlDir, String tempDir, File reportHtmlDir, File styleDir) throws Exception {
XMLResultAggregator task = new XMLResultAggregator();
task.setProject(prj);
FileSet fs = new FileSet();
fs.setDir(reportXmlDir);
fs.setIncludes("TEST-*.xml");
task.addFileSet(fs);
task.setTodir(reportXmlDir);
//必须设置,否则会空指针异常
prj.setProperty("java.io.tmpdir", tempDir);
AggregateTransformer aggregateTransformer = task.createReport();
aggregateTransformer.setTodir(reportHtmlDir);
AggregateTransformer.Format format = new AggregateTransformer.Format();
format.setValue(AggregateTransformer.FRAMES);
aggregateTransformer.setFormat(format);
aggregateTransformer.setStyledir(styleDir);
task.execute();
}
通过上面的方法就可以在java中直接调用ant提供的junit test,并生成最终报告。
对于Ant的使用,还有很多,一下是我收集到的一些,有些时候在一些场合应该很不错。下面贴的是完整的类。这边还有说明下,需要的jar包在ANT_HOME/lib下都有。大家按照需要导入即可。
完整的类:(。。。部分为上面已经贴出部分)
AntCallSample.java
package com.eta02913.antcall;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.*;
import org.apache.tools.ant.taskdefs.optional.junit.*;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.FilterSet;
import org.apache.tools.ant.types.PatternSet;
import org.apache.tools.ant.types.ZipScanner;
import org.apache.tools.zip.*;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
/**
* Created by IntelliJ IDEA.
* User: eta02913
* Date: 11-3-28
* Time: 上午9:07
* To change this template use File | Settings | File Templates.
*/
public class AntCallSample {
//所有的Task都必须设置一个Project对象,可以共用一个Project.
private Project prj = new Project();
public void mkDir(String fileName) {
mkdir(new File(fileName));
}
public void mkdir(File file) {
Mkdir mkdir = new Mkdir();
mkdir.setProject(prj);
mkdir.setDir(file);
mkdir.execute();
}
public void deleteDir(String dirPath) {
deleteDir(new File(dirPath));
}
public void deleteDir(File dir) {
Delete delete = new Delete();
delete.setProject(prj);
delete.setDir(dir);
delete.execute();
}
public void deleteFile(File file) {
Delete delete = new Delete();
delete.setProject(prj);
delete.setFile(file);
delete.execute();
}
public void copyFileToDir(File file, File toDir, boolean isOverWrite) {
Copy copy = new Copy();
copy.setProject(prj);
copy.setFile(file);
copy.setTodir(toDir);
copy.setOverwrite(isOverWrite);
copy.execute();
}
/**
* 复制文件并替换文件中的内容
*
* @param fromDir 待复制的文件夹
* @param toDir 目标文件夹
* @param includes 包含哪些文件
* @param token 文件中待替换的字符串
* @param value 替换后的字符串
*/
public void copyAndReplace(File fromDir, File toDir, String includes, String token, String value) {
Copy copy = new Copy();
copy.setEncoding("UTF-8");
copy.setProject(prj);
copy.setTodir(toDir);
FileSet fileSet = new FileSet();
fileSet.setDir(fromDir);
fileSet.setIncludes(includes);
copy.addFileset(fileSet);
FilterSet filter = copy.createFilterSet();
filter.addFilter("eosapp_name", "app1");
copy.execute();
}
public void move(File file, File toDir) {
Copy copy = new Move();
copy.setProject(prj);
copy.setFile(file);
copy.setTodir(toDir);
copy.execute();
}
public void rename(File oldFile, File newFile) {
Copy copy = new Copy();
copy.setProject(prj);
copy.setFile(oldFile);
copy.setTodir(newFile);
copy.execute();
}
/**
* 文件集合
*
* @param dir
* @param includes 包含的文件;表达式,使用,或者空格分隔字符串,“**”代表所有文件或目录,“*.*”代表说有文件, “*.java”代表所有扩展名为java的文件
* @param excludes 排除的文件:表达式,使用,或者空格分隔字符串,“**”代表所有文件或目录,“*.*”代表说有文件, “*.java”代表所有扩展名为java的文件
*/
public void createFileSet(File dir, String includes, String excludes) {
FileSet fs = new FileSet();
fs.setProject(prj);
fs.setDir(dir);
if (isEmpty(includes)) {
includes = "**/*.*";//默认包含所有文件
}
fs.setIncludes(includes);
if (!isEmpty(excludes)) {
fs.setExcludes(excludes);
}
}
private boolean isEmpty(String str) {
return str == null || "".equals(str);
}
public void scanDir(File baseFile) {
DirectoryScanner ds = new DirectoryScanner();
ds.setBasedir(baseFile);
ds.scan();
if (ds.getIncludedFilesCount() > 0) {
String[] includeFiles = ds.getIncludedFiles();
for (String file : includeFiles) {
System.out.println(file);
}
}
}
public void zipFile(FileSet fileSet, File destFile) {
Zip zip = new Zip();
zip.setProject(prj);
zip.setDestFile(destFile);
zip.addFileset(fileSet);
zip.execute();
}
public void jarFile(FileSet fileSet, File destFile) {
Jar jar = new Jar();
jar.setProject(prj);
jar.setDestFile(destFile);
jar.addFileset(fileSet);
jar.execute();
}
public void expandAllFile(File srcFile, File destDir, boolean isOverWrite) {
Expand expand = new Expand();
expand.setProject(prj);
expand.setSrc(srcFile);
expand.setOverwrite(isOverWrite);
expand.setDest(destDir);
expand.execute();
}
public void expanFileWithPattern(File srcFile, File destDir, PatternSet patternset, boolean isOverWrite) {
Expand expand = new Expand();
expand.setProject(prj);
expand.setSrc(srcFile);
expand.setOverwrite(isOverWrite);
expand.setDest(destDir);
expand.addPatternset(patternset);
expand.execute();
}
public void createPatternSet(String includes, String excludes) {
PatternSet patternset = new PatternSet();
patternset.setProject(prj);
if (!isEmpty(includes)) {
patternset.setIncludes(includes);
}
if (!isEmpty(excludes)) {
patternset.setExcludes(excludes);
}
}
public void readZipFile(File zipFile) {
ZipFile zipfile = null;
try {
zipfile = new ZipFile(zipFile);
Enumeration entries = zipfile.getEntries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
if (entry.isDirectory()) {
System.out.println("Directory: " + entry.getName());
} else {
System.out.println("file: " + entry.getName());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (zipfile != null) {
try {
zipfile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void scanZipFile(File srcFile) {
ZipScanner scan = new ZipScanner();
scan.setSrc(srcFile);
// scan.setIncludes(new String[]);
scan.scan();
String dirs[] = scan.getIncludedDirectories();
String files[] = scan.getIncludedFiles();
}
public void simpleJunitTest(String testClassName, File reportXmlDir, boolean isFork) throws Exception {
。。。
}
public void callBatchJunitTest(String includes, boolean isFork, FileSet fs, File reportXmlDir) throws Exception {
。。。
}
private void initJunitTask(boolean isFork, JUnitTask task) {
。。。
}
private FormatterElement createFormatterElement(String value) {
。。。
}
public void createJunitReport(File reportXmlDir, String tempDir, File reportHtmlDir, File styleDir) throws Exception {
。。。 }
}
更多的方法,可以自行参考ant的api或者源码。ant的api在官网是不提供查询的,而是在下载的完整ant包里有提供。