gpt4 book ai didi

android - 如何在Android Studio中正确实现和测试“自定义 Lint 规则”?

转载 作者:搜寻专家 更新时间:2023-11-01 07:45:17 28 4
gpt4 key购买 nike

我遵循this tutorialthis Custom Detector Example以实现自定义lint规则。基本上我所做的是:
在android工作室中创建一个新的android项目;
为步骤1中创建的项目创建Java模块;
在模块的build.gralde上,导入lint api依赖项;
创建问题&issueregister&customdetector;
参考模块build.gradle上的IssuereRegister;
创建单元测试;
我的问题是,在我的JUnits执行期间,我总是收到“没有警告”。当我解除测试时,我可以看到我的自定义检测器没有被调用,我做错了什么?
字符串.java

public class Strings {

public static final String STR_ISSUE_001_ID = "VarsMustHaveMoreThanOneCharacter";
public static final String STR_ISSUE_001_DESCRIPTION = "Avoid naming variables with only one character";
public static final String STR_ISSUE_001_EXPLANATION = "Variables named with only one character do not pass any meaning to the reader. " +
"Variables name should clear indicate the meaning of the value it is holding";
}

问题.java
public class Issues {

public static final
Issue ISSUE_001 = Issue.create(
STR_ISSUE_001_ID,
STR_ISSUE_001_DESCRIPTION,
STR_ISSUE_001_EXPLANATION,
SECURITY,
// Priority ranging from 0 to 10 in severeness
6,
WARNING,
new Implementation(VariableNameDetector.class, ALL_RESOURCES_SCOPE)
);
}

发行registry.java
public class IssueRegistry extends com.android.tools.lint.client.api.IssueRegistry {
@Override
public List<Issue> getIssues() {
List<Issue> issues = new ArrayList<>();
issues.add(ISSUE_001);
return issues;
}
}

变量名称检测器.java
public class VariableNameDetector extends Detector implements Detector.JavaScanner {

public VariableNameDetector() {

}

@Override
public boolean appliesToResourceRefs() {
return false;
}

@Override
public boolean appliesTo(Context context, File file) {
return true;
}

@Override
@Nullable
public AstVisitor createJavaVisitor(JavaContext context) {
return new NamingConventionVisitor(context);
}

@Override
public List<String> getApplicableMethodNames() {
return null;
}

@Override
public List<Class<? extends Node>> getApplicableNodeTypes() {
List<Class<? extends Node>> types = new ArrayList<>(1);
types.add(lombok.ast.VariableDeclaration.class);
return types;
}

@Override
public void visitMethod(
JavaContext context,
AstVisitor visitor,
MethodInvocation methodInvocation
) {
}

@Override
public void visitResourceReference(
JavaContext context,
AstVisitor visitor,
Node node,
String type,
String name,
boolean isFramework
) {
}

private class NamingConventionVisitor extends ForwardingAstVisitor {

private final JavaContext context;

NamingConventionVisitor(JavaContext context) {
this.context = context;
}

@Override
public boolean visitVariableDeclaration(VariableDeclaration node) {
StrictListAccessor<VariableDefinitionEntry, VariableDeclaration> varDefinitions =
node.getVariableDefinitionEntries();

for (VariableDefinitionEntry varDefinition : varDefinitions) {
String name = varDefinition.astName().astValue();
if (name.length() == 1) {
context.report(
ISSUE_001,
context.getLocation(node),
STR_ISSUE_001_DESCRIPTION
);
return true;
}
}
return false;
}
}
}

build.gradle公司
apply plugin: 'java'

configurations {
lintChecks
}

ext {
VERSION_LINT_API = '24.3.1'
VERSION_LINT_API_TESTS = '24.3.1'
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "com.android.tools.lint:lint-api:$VERSION_LINT_API"
implementation "com.android.tools.lint:lint-checks:$VERSION_LINT_API"
testImplementation "com.android.tools.lint:lint-tests:$VERSION_LINT_API_TESTS"
}

jar {
manifest {
attributes('Lint-Registry': 'br.com.edsilfer.lint_rules.resources.IssueRegistry')
}
}

sourceCompatibility = "1.7"
targetCompatibility = "1.7"

testvariablenamedetector.java测试变量名称检测器
private static final String ARG_DEFAULT_LINT_SUCCESS_LOG = "No warnings.";

@Override
protected Detector getDetector() {
return new VariableNameDetector();
}

@Override
protected List<Issue> getIssues() {
return Collections.singletonList(Issues.ISSUE_001);
}

public void test_file_with_no_variables_with_length_equals_01() throws Exception {
assertEquals(
ARG_DEFAULT_LINT_SUCCESS_LOG,
lintProject(java("assets/Test.java", "public class Test {public String sampleVariable;}"))
);
}

public void test_file_with_variables_with_length_equals_01() throws Exception {
assertEquals(
ARG_DEFAULT_LINT_SUCCESS_LOG,
lintProject(java("assets/Test3.java", "public class Test {public String a;bnvhgvhj}"))
);
}
}

注意:在Java的模块中,我没有访问 assetsres文件夹的权限,这就是为什么我创建了一个 String.java并在单元测试中使用了 java(to, source)的原因-我假设这个 java方法与我在本问题顶部引用的教程链接中的 xml方法相同。

最佳答案

结果在我的案例中,问题出在junit本身。我认为我试图模拟文件的方式是错误的。下面的文本是我创建的README.md of a sample project的一部分,目的是记录我从这个api中学到的知识,并回答标题中的问题:
创建
创建一个新的android项目;
创建一个新的Java库模块-自定义lint规则一旦准备好就打包到.jar库中,因此使用它们实现它们的最简单方法是在Java模块库中;
在模块的build.gradle上:
在Java1.7中添加目标和源兼容性;
为lint api、lint检查和测试依赖项添加依赖项;
添加包含两个属性的jar packing task:Manifest-VersionLint-Registry,将第一个属性设置为1.0,将第二个属性设置为类的完整路径,该类稍后将包含问题的目录;
添加默认taslassemble
[可选]:添加将生成的.jar复制到~/.android/lint中的任务;
检查ref001并选择最适合您需要的检测器,根据它创建并实现一个类来完成检测器的角色;
仍然基于ref0001选择的文件,创建并实现一个checker类,稍后在detector的createJavaVisitor()方法中引用它;
为了srp,不要将checker放在同一个检测器类的文件中;
将生成的.jar文件从build/lib复制到~/.android/lint-如果在build.gradle上添加了一个任务,则可以跳过此步骤;
重新启动计算机-一旦创建并移到~/.android/lint中,lint应在下次程序启动时读取自定义规则。为了在android studio中设置警报框,使缓存失效并重新启动ide就足够了,但是,要在lint report上捕获您的自定义规则,可能需要重新启动计算机;
测试探测器和检查器
测试自定义规则不是一件容易的事情-主要是由于缺少官方api的文档。本节将介绍处理此问题的两种方法。此项目的主要目标是创建将针对真实文件运行的自定义规则,因此,测试文件对于测试它们是必要的。它们可以放在lint java库模块的./gradlew check文件夹中;
方法01:LintDetectorTest
确保已添加所有测试依赖项-签出sample project'ssrc/test/resources
build.gradleEnhancedLintDetectorTest.java复制到项目的测试目录中;
android studio存在一个已知的缺陷,它无法看到FileUtils.java文件夹中的文件,这些文件是解决这个问题的一个办法;
src/test/resources应返回将要进行测试的所有问题。一个很好的方法是从问题注册中心获取它们;
创建一个扩展自EnhancedLintDetectorTest.java的测试类;
实现返回待测检测器实例的方法;
使用EnhancedLintDetectorTest.java执行自定义规则的检查,并使用其result对象断言测试;
注意getDetector()来自lintFiles("test file path taking resources dir as root"),因此,您仅限于junit 3。
方法02:lint-junit规则
您可能已经注意到,方法01可能有点过于复杂,尽管您仅限于JUnit3特性。因此,GitHub user a11n创建了一个Lint JUnit Rule允许以更简单的方式测试自定义lint规则,这对junit 4和up特性很重要。有关如何使用此apprach创建测试的详细信息,请参阅他的项目README.md
当前,Lint JUnit Rule不更正测试文件的根目录,并且您可能无法看到从ide传递的测试-但是,当从命令行运行测试时,它可以工作。创建issuePR以修复此错误。

关于android - 如何在Android Studio中正确实现和测试“自定义 Lint 规则”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45846014/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com