上一篇大大概概的从整个执行的路径来理了一下。这一篇。着重看一下,testng这个框架的一个很重要的组成部分:自定义注释的使用。
说起来,自定义注释在之前,我是完全不了解它是干嘛用的。直到某次心血来潮的面试。我记得那个是有赞的测试,上来就问我各种java编程的基础知识,其他都还了解,就是当时问了我一下自定义注释的东西。我表示完全没用过,后来才专门学习了解了一下。
在testng里边有两个很重要的注释:
@Test、@Dataprovoider。这一篇就是专门来分析这两个典型的注释
之前的博文讲过,testng执行的最底层的入口,就是testrunner,我们来看下他的执行来源,是怎么得到的(testMethods)
private void init() {
initMetaGroups(m_xmlTest);
initRunInfo(m_xmlTest);
// Init methods and class map
// JUnit behavior is different and doesn't need this initialization step
if(!m_xmlTest.isJUnit()) {
@retinder-->这里初始化要执行的测试方法
initMethods();
}
initListeners();
addConfigurationListener(m_confListener);
}
ITestMethodFinder testMethodFinder
= new TestNGMethodFinder(m_runInfo, m_annotationFinder);
IClass[] classes = m_testClassFinder.findTestClasses();
TestNGMethodFinder的构造函数就会通过注释加载类名跟方法了
核心的代码块如下:
AnnotationHelper:预先定义好所有的复合条件的注释
private static Class[] ALL_ANNOTATIONS = new Class[] {
ITestAnnotation.class, IConfigurationAnnotation.class,
IBeforeClass.class, IAfterClass.class,
IBeforeMethod.class, IAfterMethod.class,
IDataProviderAnnotation.class, IExpectedExceptionsAnnotation.class,
IFactoryAnnotation.class, IParametersAnnotation.class,
IBeforeSuite.class, IAfterSuite.class,
IBeforeTest.class, IAfterTest.class,
IBeforeGroups.class, IAfterGroups.class
};
@retinder-->然后按照这些规则来过滤跟加载
/**
* @returns true if this class contains TestNG annotations (either on itself
* or on a superclass).
*/
public static boolean isTestNGClass(Class c, IAnnotationFinder annotationFinder) {
Class[] allAnnotations= AnnotationHelper.getAllAnnotations();
Class cls = c;
try {
for(Class annotation : allAnnotations) {
for (cls = c; cls != null; cls = cls.getSuperclass()) {