如何在Java中获得最佳代码覆盖率?

时间:2009-11-18 11:40:16

标签: java algorithm testing code-coverage

存在一些允许计算一组测试的路径覆盖率的工具,但是是否有一个工具(或算法)可以建议值以尽可能少的测试获得最佳路径覆盖?

例如,使用以下类:

public class User {

    private boolean isAdmin = false;
    private String name;
    private String password;

    public User(String name, String password, boolean isAdmin) {
        this.name = name;
        this.password = password;
        this.isAdmin = isAdmin;
    }

    public boolean isAdmin() {
        return isAdmin;
    }

    public boolean authenticate(String name, String password) {
        if (name.equals(this.name) && password.equals(this.password)) {
        return true;
        } else {
            return false;
        }
    }
}

public class DataRepository {

    List<String> data = new ArrayList<String>();

    public void add(String dataPiece) {
        data.add(dataPiece);
    }

    public void clearAll(User userAuthenticated) {
        if (userAuthenticated.isAdmin()) {
            data.clear();
        }
    }

    public void addAll(User userAuthenticated, List<String> collection) {
        if (userAuthenticated.isAdmin()) {
            data.addAll(collection);
        }
    }
}

如果我在 true 创建一个使用用户 isAdmin 的测试,我将获得更好的测试覆盖率。

是否有一个工具可以提及:如果您使用用户创建一个测试 isAdmin true ,您将获得最佳测试覆盖率

类似的东西,但对于更复杂的情况,并检查所有代码分支。

4 个答案:

答案 0 :(得分:6)

你在谈论什么“价值观”?

代码覆盖通过检查特定会话期间执行的行/方法/类等来工作。这通常在运行自动化单元测试时使用,但不一定是这样(例如,您可以在部署Web应用程序之前进行烟雾测试,以了解您在特定测试中未涵盖的代码路径)

增加覆盖范围的方法只是确保在正在测量的任何内容(例如单元测试)的上下文中,使用执行更多内部分支的参数调用更多方法。没有任何工具可以准确地告诉您要写什么 - 他们突出显示未经过测试的内容,并且由您来编写将要执行此操作的测试。

除非您的问题是“哪种覆盖工具为覆盖率提供了最高的测量值”,否则这是评估适用性的不良标准。

编辑 - 您还需要意识到测试的目标不是获得良好的覆盖率。代码覆盖率仅用于显示绝对不是测试的代码。一个类仍然可以有100%的覆盖率而没有任何有用的测试(例如,没有任何断言的那些 - 或者更常见的是,那些断言也传递了一些失败值的那些)。

因此,如果您只是为了获得覆盖而编写测试,那么您的测试将是垃圾并且不会给您任何东西。编写测试最初只考虑类的功能,只有当你想到“我已经完成”时,才能通过覆盖工具运行它。使用该工具的输出可以查看尚未执行的代码块,这可能表明您需要编写更多传递不同输入的测试。最重要的是,在编写测试时,请始终确定您正在测试的是什么以及哪些输出应该构成通过和失败。

答案 1 :(得分:5)

Clover具有以下功能:它向您展示了经过严格测试的高度复杂的代码。这很好,所以你不要浪费时间通过测试getter和setter来增加代码覆盖率。

许多工具可以计算函数的圈复杂度。如果此值为高,则您无法测试函数的所有排列。

代码覆盖是一种手段 - 而不是目的。代码覆盖率并不能证明代码是正确的,并且覆盖工具仅作为它可以帮助您发现的错误。

答案 2 :(得分:3)

要回答关于建议测试值的问题,你可以看看Agitar(http://www.agitar.com/)。我记得在yonks之前有一个关于它的演示文稿,我确信它已经改变了(希望更好)从那时起,但它可能是你正在寻找的。我,我自己,将继续沿着TDD的路线和我在其他答案中提到的其他事情,但如果你感兴趣,这里是Agitar网站所说的一小部分:

“AgitarOne产品系列可帮助您在开发和维护Java应用程序时更安全,更好,更智能地工作.AgitarOne JUnit Generator可为您的代码创建全面的JUnit测试。这有助于您查找回归并使其更安全,更易于改进你的代码可以降低维护它的成本。“

答案 3 :(得分:1)

测试驱动开发。如果您想获得最佳覆盖率,可以尝试测试驱逐您编写的所有代码。它需要很多规则,并且在配对程序时甚至更好,但如果你正确地做到了,我会期望100%的代码覆盖率。

另一个提示是尽可能减少您在自动测试单个类时编写的单元测试的数量,从而缩小其他类。最强大的测试(例如系统测试或验收测试或任何你想要的测试)是那些从类链中开始的(如果可能的话,在你的应用程序的入口点),然后测试没有存根或嘲笑任何东西。在最坏的情况下,您将运行一个完整的系统,只与内存数据库(例如包含测试数据的hsqldb)进行通信。编写这些测试将有助于减少测试类(以及测试)的数量,并且还可以更轻松地重构生产代码,并在将来添加新功能时维护这些测试。