TestNG的启动有两种方式:
1、命令行模式,在IDEA中也是通过该方式执行的
java org.testng.TestNg ***.xml2、new TestNG() 的实例,通过run()方法执行,使用该方式执行需要注意并不会执行configure方法,所以要求在run之前设置好参数,有些是私有参数就需要通过反射等方式进行设置,此方式扩展性更高,需要对TestNG做扩展或二次开发时,可以有效控制TestNG
TestNG的启动
/**
* The TestNG entry point for command line execution.
*
* @param argv the TestNG command line parameters.
*/
public static void main(String[] argv) {
TestNG testng = privateMain(argv, null);
System.exit(testng.getStatus());
}命令行启动会找到org.testng.TestNg类中的main方法启动。
在main方法中调用了privateMain方法。
/**
* <B>Note</B>: 此方法不是公共 API 的一部分,仅供内部使用.
*/
public static TestNG privateMain(String[] argv, ITestListener listener){
....
//
// Parse the arguments
//
try {
CommandLineArgs cla = new CommandLineArgs();
m_jCommander = new JCommander(cla);
m_jCommander.parse(argv);
validateCommandLineParameters(cla);
result.configure(cla);
} catch (ParameterException ex) {
exitWithError(ex.getMessage());
}
....
}privateMain方法中主要做的一个事情就是使用了jcommander对命令行的解析校验和配置。
在这里从CommandLineArgs类中罗列一下Testng支持的命令行参数:
/**
testng 启动suite的文件,可填写多个
*/
@Parameter(description = "The XML suite files to run")
public List<String> suiteFiles = Lists.newArrayList();常见命令如:java org.testng.TestNG testng1.xml [testng2.xml testng3.xml ...]
继续跟踪suiteFiles发现只有两处在使用
1652行是在privateMain方法中 validateCommandLineParameters(cla);执行的。
用来校验在命令行中我们是否设置了可执行用例
(可执行用例的文件有4种设置方式:-testcalass,-testjar,-methods 和上面的***.xml的方式,4种方式是如何执行的,我们后面讲)
1463行和1464行是在privateMain方法中 result.configure(cla);执行的。
设置TestNG需要执行的suite文件
public static final String LOG = "-log";
public static final String VERBOSE = "-verbose";
/**
其实就是日志的冗余级别。官方文档中解释数字越大,表示日志打的越详细。
*/
@Parameter(
names = {LOG, VERBOSE},
description = "Level of verbosity")
public Integer verbose;这个值可以指定-1~10的范围。10为最详细模式,默认为1.
注意:可以从下面代码可以看出,在命令行中使用-log/-verbose会将testng.xml中设置的verbose参数给覆盖
/** * @return the verbose level, checking in order: the verbose level on the suite, the verbose level * on the TestNG object, or 1. */ private int getVerbose(XmlSuite xmlSuite) { return xmlSuite.getVerbose() != null ? xmlSuite.getVerbose() : (m_verbose != null ? m_verbose : DEFAULT_VERBOSE); }一般在扩展TestNG时用的较多,平时编写自动化用例更多的还是关注在业务层面,想要看的话调试时在idea中设置启动参数即可。
命令行中可以使用:
java org.testng.TestNg ***.xml -log 10 java org.testng.TestNg ***.xml -verbose 8
@Parameter(names = GROUPS, description = "Comma-separated list of group names to be run")
public String groups;看名称可以看出就是我们设置的组名称。
1541行是已标记为废弃的方法,可以忽略。
1664行也是privateMain方法中 validateCommandLineParameters(cla);执行的,主要还是用于校验是否为空。
1338行是用来设置我们需要执行的组。可以看代码是吧字符串根据','split为数组存储的
/** * Define which groups will be included from this run. * * @param groups A list of group names separated by a comma. */ public void setGroups(String groups) { m_includedGroups = Utils.split(groups, ","); }命令行中可使用
java org.testng.TestNg ***.xml -groups myGroup1,myGroup2
public static final String EXCLUDED_GROUPS = "-excludegroups";
/**
不执行的组
*/
@Parameter(
names = EXCLUDED_GROUPS,
description = "Comma-separated list of group names to " + " exclude")
public String excludedGroups;-excludegroups和-groups正好相反,TestNG执行时会排除这些组的测试用例。在这里就会有个测试用例出现:-groups和-excludegroups填写了相同的组,是执行呢还是不执行呢。通过追查源码路径:
TestNG.runSuitesLocally 方法中初始化了SuiteRunners, 初始化SuiteRunner时又初始化了TestRunner,在TestRunner初始化时执行了initMethods方法,该方法中对
-beforeClassMethods,testMethods,afterClassMethods,
-beforSuiteMethods,afterSuiteMethods,
-beforXmlTestMethods,afterXmlTestMethods.
7个生命周期中需要执行的用例进行了统计。
可以从代码中看出,他们都是调用了MethodHelper.collectAndOrderMethods方法,但此时的m_excludedMethods还是一个空列表。
在MethodHelper.collectAndOrderMethods中直接调用了MethodGroupsHelper.collectMethodsByGroup方法,
可以从源码中看到,排序的方法都是includedMethods的对象,没有用到outExcludedMethods,此时只需要知道included里有没有排除组的方法就知道了。
通过跟踪代码
MethodGroupsHelper.collectMethodsByGroup -> MethodGroupsHelper.includeMethod -> runInfo.includeMethod一直追到XmlMethodSelector类中includeMethodFromIncludeExclude方法中有一段源码
在这可以看到有个判断,必须在includedGroups并且不在excludedGroups中才会返回true,
所以可以得出结论:
-groups和-excludegroups填写了相同的组,会被排除,不被执行。
public static final String OUTPUT_DIRECTORY = "-d";
@Parameter(names = OUTPUT_DIRECTORY, description = "Output directory")
public String outputDirectory;-d 就是输出测试报告的目录,不填写会默认:test-output
public static final String JUNIT = "-junit";
@Parameter(names = JUNIT, description = "JUnit mode")
public Boolean junit = Boolean.FALSE;
public static final String MIXED = "-mixed";
@Parameter(
names = MIXED,
description =
"Mixed mode - autodetect the type of current test"
+ " and run it with appropriate runner")
public Boolean mixed = Boolean.FALSE;-junit 默认为false, 开启会强制走Junit执行测试用例
-mixed 默认为false,开启会判断当前用例是否是Junit用例,是则走Junit执行,否则TestNG执行
在JUnitTestFinder中可以看到TestNG支持Junit3/4,根据包名判断是调用哪个Junit的方法。
在判断是否是Junit3测试用例中:
1、 类是否是junit.framework.Test或它的子类,并且其中有1个方法是以test开头的。
2、类中是否有suite方法,并且该方法返回的类是junit.framework.Test或它的子类。
在判断是否是Junit4测试用例中:
1、测试类有org.junit.runner.RunWith的注解或继承它的注解。
2、类中有测试方法的注解有org.junit.Test的注解或继承它的注解
先说到这,下篇再继续!!







