Skip to content

Commit

Permalink
Merge pull request alibaba#20 from xyz0001/colatest
Browse files Browse the repository at this point in the history
colatest增加在线录制功能;
  • Loading branch information
significantfrank authored May 30, 2019
2 parents 9f715d7 + 14bd47b commit ea84312
Show file tree
Hide file tree
Showing 84 changed files with 3,200 additions and 686 deletions.
Binary file added COLA MOCK 介绍.pptx
Binary file not shown.
61 changes: 53 additions & 8 deletions cola-framework/cola-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,41 @@
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>cola-test</artifactId>
<version>${cola.framework.version}</version>
<version>1.0.1-SNAPSHOT</version>
<name>cola-test</name>

<properties>
<mockito.version>1.10.19</mockito.version>
</properties>

<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.7</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
Expand All @@ -29,19 +56,15 @@
<version>3.23.1-GA</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<artifactId>mockito-all</artifactId>
<version>${mockito.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
Expand Down Expand Up @@ -77,6 +100,28 @@
<!-- Source attach plugin -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive>
<manifestEntries>
<Agent-Class>com.alibaba.cola.mock.agent.MainAgent</Agent-Class>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
Expand All @@ -91,5 +136,5 @@
</executions>
</plugin>
</plugins>
</build>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,31 @@
import java.util.List;
import java.util.Map;

import com.alibaba.cola.container.command.TestClassRunCmd;
import com.alibaba.cola.container.command.TestMethodRunCmd;
import com.alibaba.cola.mock.listener.ColaNotifier;
import com.alibaba.cola.mock.model.ColaTestDescription;
import com.alibaba.cola.mock.utils.reflection.BeanMetaUtils;

import org.apache.commons.lang3.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.Description;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import static com.alibaba.cola.mock.model.ColaTestDescription.createTestDescription;

/**
* Run test here
* @author fulan.zjf 2017年10月27日 下午3:14:21
*/
public class TestExecutor {

private static final Logger logger = LoggerFactory.getLogger(TestExecutor.class);
private ColaNotifier notifier = new ColaNotifier();
private String className;
private String methodName;
Expand All @@ -36,54 +45,39 @@ public TestExecutor(ApplicationContext context){
this.context = context;
}

public void testClass() throws Exception {
public void execute(TestClassRunCmd cmd) throws Exception {
setClassName(cmd.getClassName());

Class<?> testClz = Class.forName(className);
Object testInstance = getTestInstance(testClz);
//刷新
//ColaMockito.g().refreshScanMockFromTest(testClz);
runClassTest(testClz, testInstance);
runClassTest(cmd, testClz, testInstance);
}

public void testMethod() throws Exception {
public void execute(TestMethodRunCmd cmd) throws Exception {
setClassName(cmd.getClassName());
setMethodName(cmd.getMethodName());

Class<?> testClz = Class.forName(className);
Object testInstance = getTestInstance(testClz);
//刷新
//if(ColaMockito.g().getContext().isRecording()) {
// ColaMockito.g().refreshScanMockFromTest(testClz);
//}
runMethodTest(testClz, testInstance);
runMethodTest(cmd, testClz, testInstance);
}

private void runMethodTest(Class<?> testClz, Object testInstance) throws Exception{
Method[] allMethods = testClz.getMethods();
Method beforeMethod = null;
Method afterMethod = null;
for (Method method : allMethods){
Annotation[] annotations = method.getAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof Before){
beforeMethod = method;
break;
}
if(annotation instanceof After){
afterMethod = method;
break;
}
}
}
private void runMethodTest(TestMethodRunCmd cmd, Class<?> testClz, Object testInstance) throws Exception{
Method beforeMethod = BeanMetaUtils.findMethod(testClz, Before.class);
Method afterMethod = BeanMetaUtils.findMethod(testClz, After.class);
Method method = testClz.getMethod(methodName);
Description description = Description.createTestDescription(testClz, method.getName());
notifier.fireTestRunStarted(testInstance);
notifier.fireTestRunStarted(description);

ColaTestDescription colaDes = ColaTestDescription.createTestDescription(cmd, testInstance, method);
notifier.fireTestRunStarted(colaDes);
//invoke before method
invokeMethod(testInstance, beforeMethod);
notifier.fireTestStarted(method, description);
notifier.fireTestStarted(method, colaDes.getDescription());
//invoke test method
invokeMethod(testInstance, method);
notifier.fireTestFinished(method, description);
notifier.fireTestFinished(method, colaDes.getDescription());
//invoke after method
invokeMethod(testInstance, afterMethod);
notifier.fireTestRunFinished(description);
notifier.fireTestRunFinished(colaDes.getDescription());
}

private Object getTestInstance(Class<?> testClz) throws Exception{
Expand All @@ -95,8 +89,8 @@ private Object getTestInstance(Class<?> testClz) throws Exception{
return testInstance;
}

private void runClassTest(Class<?> testClz, Object testInstance)throws Exception{
Description description = Description.createSuiteDescription(testClz);
private void runClassTest(TestClassRunCmd cmd, Class<?> testClz, Object testInstance)throws Exception{
ColaTestDescription colaDes = ColaTestDescription.createTestDescription(cmd, testInstance);
Method[] allMethods = testClz.getMethods();
Method beforeMethod = null;
Method afterMethod = null;
Expand All @@ -114,26 +108,27 @@ private void runClassTest(Class<?> testClz, Object testInstance)throws Exception
}
if(annotation instanceof Test || method.getName().startsWith("test")){
testMethods.add(method);
description.addChild(Description.createTestDescription(testClz, method.getName()));
colaDes.getDescription().addChild(Description.createTestDescription(testClz, method.getName()));
break;
}
}
}
notifier.fireTestRunStarted(testInstance);
notifier.fireTestRunStarted(description);
//notifier.fireTestRunStarted(testInstance, command);

notifier.fireTestRunStarted(colaDes);
//invoke before method
invokeMethod(testInstance, beforeMethod);
//invoke test methods
for(Method testMethod: testMethods){
notifier.fireTestStarted(testMethod, description);
notifier.fireTestStarted(testMethod, colaDes.getDescription());
//testMethodStarted(testInstance, testMethod);
invokeMethod(testInstance, testMethod);
//testMethodFinished(testInstance, testMethod);
notifier.fireTestFinished(testMethod, description);
notifier.fireTestFinished(testMethod, colaDes.getDescription());
}
//invoke after method
invokeMethod(testInstance, afterMethod);
notifier.fireTestRunFinished(description);
notifier.fireTestRunFinished(colaDes.getDescription());
}

private static void invokeMethod(Object obj, Method method) throws Exception{
Expand All @@ -152,27 +147,33 @@ private void injectWiredBean(Class<?> testClz, Object testInstance) {
String beanName = field.getName();
Annotation autowiredAnn = field.getDeclaredAnnotation(Autowired.class);
if (autowiredAnn == null) {
System.out.println("Field "+beanName+" is not autowired, just ignore it");
continue;
}
try {
field.setAccessible(true);
field.set(testInstance, context.getBean(beanName));
} catch (IllegalArgumentException e){
e.printStackTrace();
}catch (BeansException | IllegalAccessException e) {
//try to use type to get bean
try {
field.set(testInstance, context.getBean(field.getType()));
} catch (Exception innerE) {
System.err.println("oops!!! "+beanName + " can not be injected to "+ className);
System.err.println(innerE.getMessage());
}
}
trySetFieldValue(field, testInstance, beanName);
}
}


private void trySetFieldValue(Field field, Object testInstance, String beanName){
try {
field.setAccessible(true);
field.set(testInstance, context.getBean(beanName));
return;
} catch (IllegalArgumentException e){
if(StringUtils.isNotBlank(e.getMessage()) && e.getMessage().indexOf("\\$Proxy") > 0){
logger.error("此错误一般是实际类被代理导致,请尝试把字段类型改为接口!", e);
throw e;
}
}catch (BeansException | IllegalAccessException e) {
logger.warn("根据beanName查找失败,尝试byType查找");
}

try {
field.set(testInstance, context.getBean(field.getType()));
} catch (Exception innerE) {
logger.error("oops!!! "+beanName + " can not be injected to "+ className, innerE);
}
}

/**
* @return the className
*/
Expand Down
Loading

0 comments on commit ea84312

Please sign in to comment.