一.背景
在使用maven surefire插件命令:mvn test -Dtest=测试类进行测试时,对于stdout信息进行识别能迅速的发现问题,当某个suite类聚合了几千个用例时,失败数往往有几十甚至上百(虽然surefire支持运行中重试,但几千个用例同时运行时,同时申请资源,比如测试账号时,资源不够;或者并发量太大,测试环境web容器扛不住等),有必要进行迭代重试,而surefire生成的stdout Results结果没有成功和skipped用例,失败的用例信息格式多样,不便提取到有用信息;故修改surefire源码,统一格式输出。
标准的stdout如下:
二.解决办法
修改surefire源码,将执行结果输出进行统一格式输出,便于正则匹配,作为物料供重试使用(JUnitCore类)。
surefire github:https://github.com/apache/maven-surefire
1.下载源码
git clone https://github.com/apache/maven-surefire.git
2.修改源码
package org.apache.maven.plugin.surefire.report;
DefaultReporterFactory.java;
使用工厂模式,监听执行结果,判断测试方法执行结果,放到各自map中,再输出,可以看注释分析。
package org.apache.maven.plugin.surefire.report;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.plugin.surefire.StartupReportConfiguration;
import org.apache.maven.plugin.surefire.runorder.StatisticsReporter;
import org.apache.maven.surefire.report.DefaultDirectConsoleReporter;
import org.apache.maven.surefire.report.ReporterFactory;
import org.apache.maven.surefire.report.RunListener;
import org.apache.maven.surefire.report.RunStatistics;
import org.apache.maven.surefire.report.StackTraceWriter;
import org.apache.maven.surefire.suite.RunResult;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* Provides reporting modules on the plugin side.
* <p/>
* Keeps a centralized count of test run results.
*
* @author Kristian Rosenvold
*
* modify by hugang
* stdout success and skipped
*/
public class DefaultReporterFactory
implements ReporterFactory
{
private RunStatistics globalStats = new RunStatistics();
private final StartupReportConfiguration reportConfiguration;
private final StatisticsReporter statisticsReporter;
private final List<TestSetRunListener> listeners =
Collections.synchronizedList( new ArrayList<TestSetRunListener>() );
// from "<testclass>.<testmethod>" -> statistics about all the runs for flaky tests
private Map<String, List<TestMethodStats>> flakyTests;
// from "<testclass>.<testmethod>" -> statistics about all the runs for failed tests
private Map<String, List<TestMethodStats>> failedTests;
// from "<testclass>.<testmethod>" -> statistics about all the runs for error tests
private Map<String, List<TestMethodStats>> errorTests;
// added by hugang, from "<testclass>.<testmethod>" -> statistics about all the runs for success tests
private Map<String, List<TestMethodStats>> successTests;
// added by hugang, from "<testclass>.<testmethod>" -> statistics about all the runs for skipped tests
private Map<String, List<TestMethodStats>> skippedTests;
public DefaultReporterFactory( StartupReportConfiguration reportConfiguration )
{
this.reportConfiguration = reportConfiguration;
this.statisticsReporter = reportConfiguration.instantiateStatisticsReporter();
}
public RunListener createReporter()
{
return createTestSetRunListener();
}
public void mergeFromOtherFactories( Collection<DefaultReporterFactory> factories )
{
for ( DefaultReporterFactory factory : factories )
{
for ( TestSetRunListener listener : factory.listeners )
{
listeners.add( listener );
}
}
}
public RunListener createTestSetRunListener()
{
TestSetRunListener testSetRunListener =
new TestSetRunListener( reportConfiguration.instantiateConsoleReporter(),
reportConfiguration.instantiateFileReporter(),
reportConfiguration.instantiateStatelessXmlReporter(),
reportConfiguration.instantiateConsoleOutputFileReporter(), statisticsReporter,
reportConfiguration.isTrimStackTrace(),