背景:
根据case的上的注解@CaseTag 的key 与val 内容来筛选case
一、筛选器@CaseSelector
RunRedLine
package com.example.autoapi.cases.run;
import com.example.autoapi.annotation.CaseSelector;
public class RunRedLine {
@CaseSelector(scanPackage = "com.example.autoapi.cases.login",key="level",val="redLine")
public void redLine(){
}
}
编写筛选case的方法。
同样也是通过自定义注解@CaseSelector,scanPackage 里填写包名,运行这个包下 ,所有case
@CaseTag ,key=level ,val= redLine 的case。
注解,筛选器
CaseSelector
package com.example.autoapi.annotation;
import com.example.autoapi.extension.CaseAnnotationCheckExtension;
import com.example.autoapi.extension.CaseSelectorExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.ANNOTATION_TYPE,ElementType.METHOD}) // Target表示将来这个注解应用在哪些方面。注解可以应用在类上、方法上(此处只应用在方法上)
@Retention(RetentionPolicy.RUNTIME) //运行时,使用这个这个注解
@Test
@ExtendWith(CaseSelectorExtension.class) // 与junit结合,由junit提供。自定义一个扩展类,然后放到这里。走我们的自定义类
public @interface CaseSelector {
String scanPackage();
String key();
String val();
}
自定义扩展类
CaseSelectorExtension
package com.example.autoapi.extension;
import com.example.autoapi.annotation.CaseSelector;
import com.example.autoapi.extension.filter.CaseTagFilter;
import com.example.autoapi.util.RequireUtil;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.platform.engine.DiscoverySelector;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import java.lang.reflect.Method;
public class CaseSelectorExtension implements BeforeTestExecutionCallback{
@Override
public void beforeTestExecution(ExtensionContext extensionContext) throws Exception {
Method method = extensionContext.getRequiredTestMethod();
// 获取注解CaseSelector信息
CaseSelector caseSelector = method.getAnnotation(CaseSelector.class);
// 验证/校验 注解信息
verify(caseSelector);
//----开始进行是筛选----
// 先筛选包
// 再按照@CaseTag key value筛选
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
// 根据包筛选case
.selectors(DiscoverySelectors.selectPackage(caseSelector.scanPackage()))
// 根据注解CaseTag筛选case
.filters(new CaseTagFilter(caseSelector))
.build();
Launcher launcher = LauncherFactory.create();
launcher.execute(request);
// ----以上固定结构,框架提供能力
// 根据CaseTag 筛选,这里是需要自己写的CaseTagFilter
}
private void verify(CaseSelector caseSelector){
RequireUtil.requireNotNullOrEmpty(caseSelector.scanPackage(),"scanPackage is must");
}
}
这个类里,实现了根据包筛选case和根据casetag筛选case的功能
根据包筛选case,这个是框架的能力,固定格式
根据注解CaseTag筛选case,这个是我们自己写的。CaseTagFilter
CaseTagFilter
package com.example.autoapi.extension.filter;
import com.example.autoapi.annotation.CaseSelector;
import com.example.autoapi.annotation.CaseTag;
import org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor;
import org.junit.platform.engine.FilterResult;
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.launcher.PostDiscoveryFilter;
import java.lang.reflect.Method;
import java.util.Arrays;
public class CaseTagFilter implements PostDiscoveryFilter {
private CaseSelector caseSelector;
public CaseTagFilter(CaseSelector caseSelector) {
this.caseSelector = caseSelector;
}
@Override
public FilterResult apply(TestDescriptor testDescriptor) {
if(testDescriptor instanceof TestMethodTestDescriptor){
TestMethodTestDescriptor methodTestDescriptor = (TestMethodTestDescriptor)testDescriptor;
Method testMethod = methodTestDescriptor.getTestMethod();
CaseTag[] caseTags = testMethod.getAnnotationsByType(CaseTag.class);
long count = Arrays.stream(caseTags)
.filter(caseTag -> caseTag.key().equals(caseSelector.key()) && caseTag.val().equals(caseSelector.val()))
.count();
return count>0 ? FilterResult.includedIf(true):FilterResult.includedIf(false);
}
return FilterResult.includedIf(false);
}
}