You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by rigel <ze...@gmail.com> on 2008/02/10 00:51:59 UTC
How to retrieve any params from build.xml internally to the ant
source code environment?
Hello Everyone,
I'd like to print out additional test cases descriptive info into any final
Junit report, for this I started patching "XMLJUnitResultFormatter" to
accept a custom annotation associated to tested method
So now to parameterize well the annotation introspection, I need some
information on how retrieving build.xml params values strictly following
and according to ant-junit library design, but unfortunately I don't know
where to start to find a clear example of. Basically I need something to get
current params of the running target.
In "XMLJUnitResultFormatter" I implemented the generation of a nested child
tag set into tag of the JUnit xml raw data report. But these tags are
brutally wired by an "user space" annotation class. The following shows
wired tag into testcase tag:
[...]
This tag set is added only if testcase contains a specific annotation which
contains the following attributes:
public String title() default "Default test title";
public String desc() default "Default test description";
public String[] input() default {};
Now I would like to pass both name and attributes of the annotation directly
from the JUnit target or a nested one, but I don't know how to do it.
A more readable code sample usage of all classes that I implemented are
available
http://www.nabble.com/Regarding-%22Annotated-descriptions%22-of-new-improvements-in-version-4.4-td15348555.html
here and presents a wired solution.
However here I put (my painful written code, sorry for my awful style %-| )
what I modified to accomplish this. All text formatting follows my
unconventional style, and I hope it will be readable even if Nabble try to
explode in one line:wistle: ):
Here I attached my actual code with all modified/patched Ant sources:
http://www.nabble.com/file/p15391637/XMLConstants.java XMLConstants.java
http://www.nabble.com/file/p15391637/XMLJUnitResultFormatter.java
XMLJUnitResultFormatter.java
http://www.nabble.com/file/p15391637/JUnitVersionHelper.java
JUnitVersionHelper.java
http://www.nabble.com/file/p15391637/junit-frames.xsl A customized
stylesheet used by ANT JUnit to produce the final testcase report
("testcase.test.header" & "testcase" template lightly modified with appended
additions)
http://www.nabble.com/file/p15391637/TestInfo.java Custom descriptive
annotation
http://www.nabble.com/file/p15391637/EnumTestType.java An optional Enum used
by custom annotation just to complicat more :p :-D
http://www.nabble.com/file/p15391637/SampleTest.java Testcase sample using
custom annotation
http://www.nabble.com/file/t906682/6_TestBigRationalFraction.html JUnit
descriptive report sample
// ===org.apache.tools.ant.taskdefs.optional.junit.XMLConstants===
//
// Some consts referring to additional tag set
//
+++
[...]
/**
* info element for testcase element
* @author rigel alias zetatau
* TODO:
*/
String TESTINFO = "info";
/**
* title element for info element
* @author rigel alias zetatau
* TODO:
*/
String TESTINFO_TITLE = "title";
/**
* desc element for info element
* @author rigel alias zetatau
* TODO:
*/
String TESTINFO_DESC = "desc";
/**
* input element for testcase element
* @author rigel alias zetatau
* TODO:
*/
String TESTINPUT = "input";
/**
* item element for input element
* @author rigel alias zetatau
* TODO:
*/
String TESTINPUT_ITEM = "input-item";
/**
* id attribute for testcase item
* @author rigel alias zetatau
* TODO:
*/
String ATTR_TESTINPUT_ITEM_ID = "id";
/**
* type attribute for testcase item
* @author rigel alias zetatau
* TODO:
*/
String ATTR_TESTINPUT_ITEM_TYPE = "type";
[...]
+++
// ===org.apache.tools.ant.taskdefs.optional.junit.JUnitVersionHelper===
//
// Reflection routines used to get testcase annotation info (mantaining
JDK1.2 compiler compliance only, not granted correct execution@runtime)
//
+++
[...]
/** constant for unnnamed testsuites/cases */
private static final String UNKNOWN = "unknown";
private static final String JUNIT_TESTFACADE =
"junit.framework.JUnit4TestCaseFacade";
final static int DATA=0,TYPE=1;
public static String getTestCaseStringAtt(Test test, String
annotationMatch, String annotationParameter) {
if (test != null) {
if (test.getClass().getName().equals(JUNIT_TESTFACADE)) {
String sOut =
String.valueOf(helperMethodInvoke(test,annotationMatch,annotationParameter,UNKNOWN)[DATA][0]);
if (!sOut.equals(UNKNOWN))
return sOut;
} else
return "";
}
return UNKNOWN;
}
public static Object[][] getTestCaseStringArrayAtt(Test test, String
annotationMatch, String annotationParameter) {
if (test != null) {
if (test.getClass().getName().equals(JUNIT_TESTFACADE)) {
Object[][] rt =
helperMethodInvoke(test,annotationMatch,annotationParameter,UNKNOWN);
if (rt.length==0)
return new Object[0][0];
if (rt.length==0)
return new Object[][]{rt[DATA],{}};
rt = new Object[][]{rt[DATA],new Object[rt[DATA].length]};
for (int i=0; i
private static Iterator helperDescriptorCollection(Test facade) {
final String
junitDescription="org.junit.runner.Description",
methodOnFacade="getDescription",
methodOnItem="getAnnotations";
ArrayList empty = new ArrayList();
if (!facade.getClass().getName().equals(JUNIT_TESTFACADE))
return empty.iterator();
try {
Class.forName(junitDescription,false,ClassLoader.getSystemClassLoader());
// otherwise throw an exception
Method m = facade.getClass().getMethod(methodOnFacade, new Class[0]);
Object itemInstance = m.invoke(facade, new Object[0]);
if
(itemInstance!=null&&junitDescription.equals(itemInstance.getClass().getName())){
Method m1 = itemInstance.getClass().getMethod(methodOnItem, new
Class[0]);
Object rtObj = m1.invoke(itemInstance, new Object[0]);
if (rtObj instanceof Collection)
return ((Collection)rtObj).iterator();
return empty.iterator();
} else return empty.iterator();
} catch (ClassNotFoundException e) {
} catch (SecurityException e) {
} catch (IllegalArgumentException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return empty.iterator();
}
private static Object helperAnnotation(Test façade, String annotationMatch)
{
final String methodOnAnnotation="annotationType";
Object item=null;
Iterator it = helperDescriptorCollection(façade);
while (it.hasNext()) {
Object a = (Object)it.next();
String match = "";
try {
Method m = a.getClass().getMethod(methodOnAnnotation, new Class[0]);
Class out = (Class)m.invoke(a, new Object[0]);
match=String.valueOf(out.getName());
} catch (SecurityException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
if (annotationMatch.equals(match)) {
item=a;
break;
}
}
return item;
}
private static Object[][] helperMethodInvoke(Test instance, String
annotationMatch, String methodName, String defaultValue) {
try {
/*
* ANNOTATIONS WORKS DOES NOT WORK UNDER JDK 1.5
Iterator it =
(junit.framework.JUnit4TestCaseFacade)instance).getDescription().getAnnotations().iterator();
java.lang.annotation.Annotation item=null;
while (it.hasNext()) {
java.lang.annotation.Annotation a =
(java.lang.annotation.Annotation)it.next();
if (annotationMatch.equals(a.annotationType().getName())) {
item=a;
break;
}
}*/
Object item = helperAnnotation(instance, annotationMatch);
/* No appropriate annotation was found so returns defaultValue */
if (item==null)
return new Object[][]{new String[]{defaultValue},{}};
Method m = item.getClass().getMethod(methodName, new Class[0]);
Object oOut = m.invoke(item, new Object[0]);
if (oOut instanceof String) {
String sOut = String.valueOf(oOut);
if ("".equals(sOut)||sOut==null)
return new Object[][]{new String[]{defaultValue},{}};
else
return new Object[][]{new String[]{sOut},{}};
} else if (oOut instanceof String[]) {
return new Object[][]{(String[])oOut,{}};
} else if (oOut instanceof Enum) {
return new Object[][]{new String[]{String.valueOf(oOut)},{}};
} else {
return new Object[][]{new String[]{defaultValue},{}};
}
} catch (SecurityException e) {
} catch (IllegalArgumentException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return new Object[][]{new String[]{defaultValue}};
}
public static String predictDataType(Object obj) {
String sPlain = String.valueOf(obj);
String sPlainType = obj.getClass().getName();
Number nTest=null;
try {
nTest = new BigDecimal(sPlain);
if (nTest.toString().equals(sPlain))
sPlainType=nTest.getClass().getName();
} catch (NumberFormatException e) {}
try {
nTest = new BigInteger(sPlain);
if (nTest.toString().equals(sPlain))
sPlainType=nTest.getClass().getName();
} catch (NumberFormatException e) {}
try {
nTest = new Double(sPlain);
if (nTest.toString().equals(sPlain))
sPlainType=nTest.getClass().getName();
} catch (NumberFormatException e) {}
try {
nTest = new Long(sPlain);
if (nTest.toString().equals(sPlain))
sPlainType=nTest.getClass().getName();
} catch (NumberFormatException e) {}
try {
nTest = new Float(sPlain);
if (nTest.toString().equals(sPlain))
sPlainType=nTest.getClass().getName();
} catch (NumberFormatException e) {}
try {
nTest = new Integer(sPlain);
if (nTest.toString().equals(sPlain))
sPlainType=nTest.getClass().getName();
} catch (NumberFormatException e) {}
try {
nTest = new Byte(sPlain);
if (nTest.toString().equals(sPlain))
sPlainType=nTest.getClass().getName();
} catch (NumberFormatException e) {}
try {
nTest = new Short(sPlain);
if (nTest.toString().equals(sPlain))
sPlainType=nTest.getClass().getName();
} catch (NumberFormatException e) {}
return sPlainType;
}
[...]
+++
//
===org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter===
//
// Additional tag set inserted into testcase and composed by information
retrieved by custom annotation
//
+++
public void endTest(Test test) {
[...]
/*
* This adds additional info to the generated XML test case data,
unfortunately I don't
* know what ant helper class can give me some params from XML build
*/
String sType =
JUnitVersionHelper.getTestCaseStringAtt(test,"test.TestInfo",ATTR_TESTTYPE);
if (!UNKNOWN.equals(sType)) {
currentTest.setAttribute(ATTR_TESTTYPE,sType);
}
String sTypeId =
JUnitVersionHelper.getTestCaseStringAtt(test,"test.TestInfo",ATTR_TESTTYPEID);
if (!UNKNOWN.equals(sTypeId)) {
currentTest.setAttribute(ATTR_TESTTYPEID,sTypeId);
}
Element currentTestInfo = doc.createElement(TESTINFO);
String sTitle =
JUnitVersionHelper.getTestCaseStringAtt(test,"test.TestInfo",TESTINFO_TITLE);
if (!UNKNOWN.equals(sTitle)) {
CDATASection titleNode = doc.createCDATASection(sTitle);
Element currentTestInfoTitle = doc.createElement(TESTINFO_TITLE);
currentTestInfoTitle.appendChild(titleNode);
currentTestInfo.appendChild(currentTestInfoTitle);
}
String sDesc =
JUnitVersionHelper.getTestCaseStringAtt(test,"test.TestInfo",TESTINFO_DESC);
if (!UNKNOWN.equals(sDesc)) {
CDATASection descNode = doc.createCDATASection(sDesc);
Element currentTestInfoDesc = doc.createElement(TESTINFO_DESC);
currentTestInfoDesc.appendChild(descNode);
currentTestInfo.appendChild(currentTestInfoDesc);
}
final int DATA=0, TYPE=1;
Object[][] aInput =
JUnitVersionHelper.getTestCaseStringArrayAtt(test,"test.TestInfo",TESTINPUT);
if (aInput.length>0) {
Element currentTestInput = doc.createElement(TESTINPUT);
if (aInput[DATA].length>=1) {
if (!String.valueOf(aInput[DATA][0]).equals(UNKNOWN)) {
for (int i=0; i
Element currentTestInputItem = doc.createElement(TESTINPUT_ITEM);
currentTestInputItem.setAttribute(ATTR_TESTINPUT_ITEM_ID,String.valueOf(i));
if (aInput[TYPE].length>0)
currentTestInputItem.setAttribute(ATTR_TESTINPUT_ITEM_TYPE,String.valueOf(aInput[TYPE][i]));
else
currentTestInputItem.setAttribute(ATTR_TESTINPUT_ITEM_TYPE,String.class.getName());
CDATASection inputNode =
doc.createCDATASection(String.valueOf(aInput[DATA][i]));
currentTestInputItem.appendChild(inputNode);
currentTestInput.appendChild(currentTestInputItem);
}
}
}
currentTestInfo.appendChild(currentTestInput);
}
currentTest.appendChild(currentTestInfo);
[...]
}
+++
Thank You
--
View this message in context: http://www.nabble.com/How-to-retrieve-any-params-from-build.xml-internally-to-the-ant-source-code-environment--tp15391637p15391637.html
Sent from the Ant - Dev mailing list archive at Nabble.com.