我正在构建一个识别测试类的程序,并让编码器知道他编写的测试代码与实际源代码相比有多少。我的问题是,尽管已经使用了类型的测试,我怎样才能使程序识别出测试类?你可以在测试课中找到什么主要标志?是@Test
符号吗?如果是这样如何处理呢?
这是我用来识别测试类的类的一段代码:
public void walk(String path) throws FileNotFoundException {
int countFiles = 0;
File root = new File(path);
File[] list = root.listFiles();
if (list == null) {
return;
}
for (File f : list) {
if (f.isDirectory()) {
walk(f.getAbsolutePath());
}
if (f.getName().endsWith(".java")) {
System.out.println("File:" + f.getName());
Scanner sc2 = new Scanner(f);
while (sc2.hasNextLine()) {
count++;
String str = sc2.nextLine();
for (int i = 0; i < str.length(); i++) {
if(str.equals("@Test")){
System.out.println("this a test clsee!");
}
但不幸的是我的想法不起作用。那我该怎么办?
答案 0 :(得分:1)
我意识到这可能不是你想要的答案,但是让我给你两个不同的想法。
如果您使用maven或gradle作为构建工具,则应该拥有所有内容
无论如何,你在src/test/java
文件夹中的测试类,使其变得容易
区别于您的生产代码(位于
src/main/java
文件夹)。其他工具可能具有类似的结构。
如果你没有,你可能想考虑转换。
一旦您的测试代码和生产代码不同
文件夹,您只需计算这些文件夹中的所有*.java
个文件
结构(或写一个bat / bash /无论什么脚本为你做)。
由于纯粹的测试代码并没有真正告诉您有关实际test coverage的任何信息,因此您可能需要寻找一种工具来帮助您衡量此覆盖率并专注于< em> quality 而不是测试的数量。
如果您使用的是Eclipse,则可以使用Eclipse。 EclEmma(这可能不是唯一的,不是最好的,而只是我正在使用的那个)。它为Eclipse添加了一个新的启动模式,然后您可以在 Coverage 模式下启动单元测试。在这种模式下,EclEmma会记录测试运行时生产代码的哪些行,这样您就可以很好地了解代码的哪些部分已经过测试,哪些部分未经过测试。它还计算一些关于所覆盖的线或分支的百分比的统计数据,以帮助您识别弱点。
(现在至少要快速解决你的代码:理论上你的方法应该有效。在实践中,看起来你应该阅读java中的字符串比较。替换你的str.equals("@Test")
循环可能值得一试使用简单的str.contains("@Test")
。)
答案 1 :(得分:0)
更新:例如,代替代码:
Scanner sc2 = new Scanner(f);
while (sc2.hasNextLine()) {
count++;
String str = sc2.nextLine();
for (int i = 0; i < str.length(); i++) {
if(str.equals("@Test")){
System.out.println("this a test clsee!");
您应该使用代码:
Scanner sc2 = new Scanner(f);
boolean flag = false;
while (sc2.hasNextLine() && !flag) {
String str = sc2.nextLine();
if(str.contains("@Test")){
flag = true;
}
}
if(flag) {
System.out.println("this a test clsee!");
}
答案 2 :(得分:0)
我不确定这是否是您要找的。获得文件名后,请按照以下步骤操作。
Classfile.class.getMethods()
遍历方法数组并检查注释类
method.getAnnotation(Test.class)
正如其他人所建议的那样,最好不要将测试课程与商业代码联系在一起。
我在这里添加了完整的代码段。
公共类ClassFinder {
private static final char PKG_SEPARATOR = '.';
private static final char DIR_SEPARATOR = '/';
private static final String CLASS_FILE_SUFFIX = ".class";
private static final String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the package '%s' exists?";
public static List<Class<?>> find(String scannedPackage) {
String scannedPath = scannedPackage.replace(PKG_SEPARATOR, DIR_SEPARATOR);
URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(scannedPath);
if (scannedUrl == null) {
throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPath, scannedPackage));
}
File scannedDir = new File(scannedUrl.getFile());
List<Class<?>> classes = new ArrayList<Class<?>>();
for (File file : scannedDir.listFiles()) {
classes.addAll(find(file, scannedPackage));
}
return classes;
}
private static List<Class<?>> find(File file, String scannedPackage) {
List<Class<?>> classes = new ArrayList<Class<?>>();
String resource = scannedPackage + PKG_SEPARATOR + file.getName();
if (file.isDirectory()) {
for (File child : file.listFiles()) {
classes.addAll(find(child, resource));
}
} else if (resource.endsWith(CLASS_FILE_SUFFIX)) {
int endIndex = resource.length() - CLASS_FILE_SUFFIX.length();
String className = resource.substring(0, endIndex);
try {
classes.add(Class.forName(className));
} catch (ClassNotFoundException ignore) {
}
}
return classes;
}
public static void main(String[] args) {
List<Class<?>> classes = ClassFinder.find("com.vijay.junitapp4");
Method[] methods = null;
for (Class<?> class1 : classes) {
methods = class1.getMethods();
Test test = null;
for (int j = 0; j < methods.length; j++) {
test = methods[j].getAnnotation(Test.class);
if(null != test){
System.out.println("we found a teat case");
break;
}
}
}
}
}