上周基于JUnit写了个简单的性能测试框架,其实就是用了下Annotation,发现还是很好用的。
/**
* Performance test annotation.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PerformanceTest
{
public String name() default "";
public int times();
public boolean stopOnError() default false;
}
/**
* Base function for performance test.
*/
public class BasePerformanceTest
{
protected Logger logger = Logger.getLogger(this.getClass());
List<PerformanceData> performanceData = new ArrayList<PerformanceData>();
@BeforeClass
public static void init()
{
ServiceUtil.init();
}
@AfterClass
public static void report()
{
PerformanceReportManager.generatePerformanceReport();
}
private void execute(Method method)
{
PerformanceTest performanceTest = method.getAnnotation(PerformanceTest.class);
String name = performanceTest.name();
if (name.equals(""))
{
name = method.getName();
}
logger.debug("Start execute test case"+name);
int times = performanceTest.times();
boolean stopOnError = performanceTest.stopOnError();
PerformanceData data = new PerformanceData(name, times);
performanceData.add(data);
for (int i = 0; i < times; i++)
{
long start = System.currentTimeMillis();
boolean error = false;
try
{
method.invoke(this);
}
catch (Throwable t)
{
logger.error("Execute performance test" + name + " error.", t);
error = true;
if (stopOnError)
{
logger.error("Stop execute performance test" + name + " because of error.");
return;
}
}
long end = System.currentTimeMillis();
data.addData(end – start);
if (error)
{
data.addError();
}
}
}
@Test
public void doPerformanceTests() throws Throwable
{
Class c = this.getClass();
PerformanceReportManager.addData(c, performanceData);
Method[] methods = c.getMethods();
for (Method method : methods)
{
if (method.isAnnotationPresent(PerformanceTest.class))
{
if (method.getParameterTypes().length == 0)
{
execute(method);
}
else
{
logger.warn("Can not support execute performance test method with parameters:" + method);
}
}
}
}
}
/**
* Performance data.
*/
public class PerformanceData
{
private String name;
private int times;
private long[] data;
private int index = 0;
private long max = Long.MIN_VALUE;
private long min = Long.MAX_VALUE;
private long total = 0;
private int errors;
public PerformanceData(String name, int times)
{
this.name = name;
this.times = times;
data = new long[times];
}
public String getName()
{
return name;
}
public int getTimes()
{
return times;
}
public long[] getData()
{
return data;
}
public void addData(long data)
{
this.data[index++] = data;
max = Math.max(max, data);
min = Math.min(min, data);
total += data;
}
public long getMax()
{
return max;
}
public long getMin()
{
return min;
}
public long getAveg()
{
if (times == 0)
{
return 0;
}
return getTotal() / times;
}
public long getTotal()
{
return total;
}
public int getErrors()
{
return errors;
}
public void addError()
{
errors++;
}
}
/**
* Performance report manager.
*/
public class PerformanceReportManager
{
private static Map<Class, List<PerformanceData>> allData = new HashMap<Class, List<PerformanceData>>();
private static PerformanceReporter performanceReporter = new DirectOutputPerformanceReporter();
public static void addData(Class c, List<PerformanceData> data)
{
allData.put(c, data);
}
public static void generatePerformanceReport()
{
performanceReporter.generateReport(allData);
}
public static PerformanceReporter getPerformanceReporter()
{
return performanceReporter;
}
public static void setPerformanceReporter(PerformanceReporter performanceReporter)
{
PerformanceReportManager.performanceReporter = performanceReporter;
}
}
public interface PerformanceReporter
{
public void generateReport(Map<Class, List<PerformanceData>> allData);
}
2009年3月23日 at 16:06
:em20: 沙发