groovy用AntBuidler写unit test之并导出自定义report

 

 

背景:

 

build.xml现在我一般用build.groovy代替了,自己用AntBuilder做***,

 

1. 想在build.groovy里运行一个unit-test-suit(groovy文件),于是代码如下:

def ant = new AntBuilder()

ant.path id: 'classpath', {
	pathelement path: bin_dir
	pathelement path: gy_dir
	pathelement path: config_dir_app

	fileset dir: lib_dir, {
		include name: '*.jar'
	}
}

ant.taskdef name: "groovy", 
	classname: "org.codehaus.groovy.ant.Groovy" 

ant.groovy src: "${src_dir_test}/AppTestRun.groovy", 
	classpathref: "classpath", {
	arg value: src_dir_test
        arg value: app_name + ' Unit Test Result Report'
 }

 

2. AppTestRun.groovy如下:

 

import junit.framework.TestResult
import junit.framework.TestSuite
import junit.textui.TestRunner

import util.WebxHtmlTestListener

// src/test directory path
String dirRoot = args[0]
String testTitle = args[1]

// current classloader (GroovyClassLoader instance)
def cl = this.class.classLoader 

TestSuite suite = new TestSuite()
new File(dirRoot).eachFileRecurse{
	if(it.name.startsWith('Test') && it.name.endsWith('.groovy')){
		suite.addTestSuite(cl.parseClass(new File(it.absolutePath)))
	}
}

// customized output format
def testresult = new TestResult()
def listener = new WebxHtmlTestListener(dirRoot)
testresult.addListener(listener)
suite.run(testresult)

listener.outTestResult()
listener.outFrame(testTitle, testresult)

 

3. WebxHtmlTestListener就是用来生成html test report的了,代码如下

package util

import junit.framework.*

/**
* TIPS: test methods with same name exception
*/
class WebxHtmlTestListener implements TestListener{
	// base dir path
	String dirRoot

	// save all test result ( failure or error )
	Map results = [:]
	// test method names
	List tests = []

	int stackNumLimit = 10

	public WebxHtmlTestListener(String dirRoot){
		this.dirRoot = dirRoot
		Tpl.init("${dirRoot}/tpl/", 'utf-8')
	}

	void out(Map params, String tpl, String outputPath){
		// blueprint css file path refer to target file
		params.dir = '../tpl'
		// target file
		File f = new File("${dirRoot}/output/${outputPath}.html")
		Tpl.out(params, tpl, f.newPrintWriter())
	}

	// generate index.html / navigation.html / summury.html
	void outFrame(String title, TestResult result){
		List testLl = tests.collect{[name: it]}
		testLl.each{test ->
			if(results.error)
				test.hasError = results.error.grep{it.name == test.name}.size() > 0
			if(results.fail)
				test.hasFail = results.fail.grep{it.name == test.name}.size() > 0
		}

		def params = [:]
		params.title = title
		params.tests = testLl

		params.result = [
			errorCount: result.errorCount(), 
			failureCount: result.failureCount(), 
			wasSuccessful: result.wasSuccessful(),
		]
		out(params, 'testResultNav.html', 'testResultNav')		
		out(params, 'testResultSum.html', 'testResultSum')		
		out(params, 'testResultFrame.html', 'index')		
	}

	void outTestResult(){
		tests.eachWithIndex{testName, i ->
			def params = [:]
			params.errors = results.error?.grep{it.name == testName}
			params.fails = results.fail?.grep{it.name == testName}

			if(i > 0){
				params.pre = tests[i - 1]
			}
			if(i < tests.size() - 1){
				params.nn = tests[i + 1]
			}

			params.title = testName
			out(params, 'testResult.html', testName)
		}
	}

	String getTestName(Test test){
		String name = test.toString()
		return name.substring(0, name.indexOf('('))
	}

	public void addError(Test test, Throwable t){
		if(!results.error)
			results.error = []

		def stacks = t.stackTrace
		List ll = stacks.collect{
			[
			fileName: it.fileName,
			className: it.className, 
			methodName: it.methodName,
			lineNumber: it.lineNumber,
			isInMsg: it.fileName && it.fileName.contains('groovy')
			]
		}

		results.error << [name: getTestName(test), 
			type: 'error', 
			msg: t.message,
			stacks: ll[0..stackNumLimit]]
	}

	public void addFailure(Test test, AssertionFailedError t){
		if(!results.fail)
			results.fail = []

		def stacks = t.stackTrace
		List ll = stacks.collect{
			[
			fileName: it.fileName,
			className: it.className, 
			methodName: it.methodName,
			lineNumber: it.lineNumber,
			isInMsg: it.fileName && it.fileName.contains('groovy')
			]
		}

		results.fail << [name: getTestName(test), 
			type: 'fail', 
			msg: t.message,
			stacks: ll[0..stackNumLimit]]
	}  

	public void endTest(Test test){
	}

	public void startTest(Test test){
		tests << getTestName(test)
	}
}

 

至于Tpl,我是用smart4j做html输出的,用freemarker,groovy总报错——估计是个bug,悲剧

4.

package util

import org.lilystudio.smarty4j.*

class Tpl {
	def static engine = new Engine()

	static void init(String path, String charset){
		engine.setTemplatePath(path)
	}

	static void out(Map map, String tpl, Writer writer) {
		def template = engine.getTemplate(tpl)
		def ctx = new Context()
		ctx.putAll(map)
		template.merge(ctx, writer)
		writer.flush()
		writer.close()
	}

}
 

附件是生成的报告截图

你可能感兴趣的:(unit test)