继上篇6.4 执行用例
之前看到了suiteRunner.runTest方法的具体内容就是执行每一个
/**
* The main entry method for TestRunner.
*
* This is where all the hard work is done:
* - Invoke configuration methods
* - Invoke test methods
* - Catch exceptions
* - Collect results
* - Invoke listeners
* - etc...
*/
public void run() {
beforeRun();
try {
XmlTest test= getTest();
if(test.isJUnit()) {
privateRunJUnit(test);
}
else {
privateRun(test);
}
}
finally {
afterRun();
}
}
然后它又调用privateRun方法:
1.首先拿到
2.然后根据paraller拿到threadCount的值,若为false则线程数为1,否则就是设置的线程数(因此,线程数是否生效要取决于paraller)
3.然后再根据paraller判断是否是多线程并发执行用例,其中下面的方法的作用是该
DynamicGraph graph = createDynamicGraph(intercept(m_allTestMethods));
private void privateRun(XmlTest xmlTest) {
String parallelMode = xmlTest.getParallel();
boolean parallel = XmlSuite.PARALLEL_METHODS.equals(parallelMode)
|| "true".equalsIgnoreCase(parallelMode)
|| XmlSuite.PARALLEL_CLASSES.equals(parallelMode)
|| XmlSuite.PARALLEL_INSTANCES.equals(parallelMode);
{
// parallel
int threadCount = parallel ? xmlTest.getThreadCount() : 1;
// Make sure we create a graph based on the intercepted methods, otherwise an interceptor
// removing methods would cause the graph never to terminate (because it would expect
// termination from methods that never get invoked).
DynamicGraph graph = createDynamicGraph(intercept(m_allTestMethods));
if (parallel) {
//并发执行
if (graph.getNodeCount() > 0) {
GraphThreadPoolExecutor executor =
new GraphThreadPoolExecutor(graph, this,
threadCount, threadCount, 0, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
executor.run();
try {
long timeOut = m_xmlTest.getTimeOut(XmlTest.DEFAULT_TIMEOUT_MS);
Utils.log("TestRunner", 2, "Starting executor for test " + m_xmlTest.getName()
+ " with time out:" + timeOut + " milliseconds.");
executor.awaitTermination(timeOut, TimeUnit.MILLISECONDS);
executor.shutdownNow();
} catch (InterruptedException handled) {
handled.printStackTrace();
Thread.currentThread().interrupt();
}
}
} else {
//串行执行用例
boolean debug = false;
List freeNodes = graph.getFreeNodes();
if (debug) {
System.out.println("Free nodes:" + freeNodes);
}
if (graph.getNodeCount() > 0 && freeNodes.isEmpty()) {
throw new TestNGException("No free nodes found in:" + graph);
}
while (! freeNodes.isEmpty()) {
List> runnables = createWorkers(freeNodes);
for (IWorker r : runnables) {
//单个用例执行
r.run();
}
graph.setStatus(freeNodes, Status.FINISHED);
freeNodes = graph.getFreeNodes();
if (debug) {
System.out.println("Free nodes:" + freeNodes);
}
}
}
}
}
拓展:mybatis的缓存机制
一级缓存:同一个sqlSession中对于完全相同的查询语句
1)session 级别的缓存
在同一个 sqlSession 内,对同样的查询将不再查询数据库,直接从缓存中。
2)statement 级别的缓存
避坑: 为了避免这个问题,可以将一级缓存的级别设为 statement 级别的,这样每次查询结束都会清掉一级缓存。
二级缓存: