集成测试,但是要多少钱? - java

Improve this question

我团队中最近的一次辩论使我感到奇怪。基本主题是功能/集成测试需要涵盖多少内容和内容(确保它们不相同,但是示例无关紧要)是虚假的。

假设您有一个类似“controller”的类:

public class SomeController {
    @Autowired Validator val;
    @Autowired DataAccess da;
    @Autowired SomeTransformer tr;
    @Autowired Calculator calc;

    public boolean doCheck(Input input) {
        if (val.validate(input)) {
             return false;
        }

        List<Stuff> stuffs = da.loadStuffs(input);
        if (stuffs.isEmpty()) {
             return false;
        }

        BusinessStuff businessStuff = tr.transform(stuffs);
        if (null == businessStuff) {
            return false;
        }

       return calc.check(businessStuff);
    }
}

我们肯定需要进行大量的单元测试(例如,如果验证失败,或者数据库中没有数据……),这是毫无疑问的。

我们的主要问题和我们不能同意的是,应该进行多少集成测试:-)

我支持我们的目标是减少集成测试(测试金字塔)。我所要讲的只是一条幸福到不开心的路径,执行从最后一行返回,只是看我是否将这些东西放在一起不会爆炸。

问题在于,要说出测试结果为何为假并不是一件容易的事,这会使一些人对此感到不安(例如,如果我们仅检查返回值,则隐藏测试是绿色的)。因为有人更改了验证并且返回了false)。当然,是的,我们可以处理所有案件,但这将是一个沉重的过大的恕我直言。

是否有人对此类问题有很好的经验法则?还是建议?读?谈论?博客文章?关于这个话题吗?

在此先多谢!

PS:不好意思的例子,但是将特定的代码部分转换成例子非常困难。是的,可以争论抛出异常/使用其他返回类型等。但由于外部依赖性,我们的手或多或少受到约束。

参考方案

如果遵循以下规则,很容易弄清楚测试应该位于哪里:

  • 我们在“单元测试”级别上检查逻辑,并检查是否在“组件”或“系统”级别上调用了该逻辑。
  • 我们不使用模拟框架(mockito,jmock等)。
  • 让我们开始潜水,但首先让我们就术语达成一致:

  • 单元测试-单独检查一个方法,一个类或其中的几个
  • 组件测试-初始化应用程序的一部分,但不将其部署到App Server。示例可能是-在测试中初始化Spring Context。
  • 系统测试-需要在App Server上进行完整部署。示例可能是:将HTTP REST请求发送到远程服务器。
  • 如果我们建立一个平衡的金字塔,我们将在单元和组件级别进行大多数测试,而很少有这些测试将留给系统测试。这很好,因为较低级别的测试更快,更容易。要做到这一点:

  • 我们应该将业务逻辑尽可能降低(最好在域模型中),因为这将使我们能够轻松地独立测试它。每次您遍历对象集合并在其中放置条件时-理想情况下,应转到域模型。
  • 但是逻辑起作用的事实并不意味着它已被正确调用。那就是您需要组件测试的地方。初始化控制器以及服务和DAO,然后调用一次或两次以查看是否调用了逻辑。
  • 示例:用户名不能超过50个符号,只能包含拉丁语以及一些特殊符号。

  • 单元测试-使用正确和错误的用户名创建用户,检查是否抛出异常,反之亦然-有效的名称正在传递
  • 组件测试-检查是否在将无效用户传递给Controller时(如果使用Spring MVC,则可以使用MockMVC进行此操作)是否引发错误。在这里,您只需要传递一个用户-到目前为止,所有规则都已经检查过,在这里,您只想知道是否调用了这些规则。
  • 系统测试-在这种情况下,您可能实际上不需要它们。

    Here is a more elaborate example如何实现平衡金字塔。

    单元测试休息点 - java

    我已经用Java编写了REST端点。应用程序中有c#代码使用RestClient调用这些端点。我正在考虑为这些编写单元测试。只是想知道什么是最好的方法? Moq框架或NUNIT还是其他?有任何想法吗?谢谢。 参考方案 如果要在Java中测试REST端点,则可以使用Mockito(https://site.mockito.org/)之类的模拟框架来模拟所需的任…

    Java:线程池如何将线程映射到可运行对象 - java

    试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

    减少测试用例之间的耦合 - java

    我试图学习有关JUnit和TDD的更多信息,但是我遇到了一些测试用例之间的耦合问题。当我为特定数据类型的API编写测试用例时,比如说Deque<T>,如何限制测试用例之间的耦合?例如,如果我正在为insertFirst(T item)方法编写一个测试用例,那么似乎很容易假设我应该能够在正确初始化的对象上调用该方法之后断言两件事: Deque对象的…

    JAVA:字节码和二进制有什么区别? - java

    java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

    在没有静态测试数据库的情况下,如何使DAO类的单元测试变脆? - java

    这是scanario:我正在研究一个DAO对象,该对象使用休眠条件API来形成许多复杂的查询,以对数据库执行某些任务(例如,跨多个字段的关键字搜索)。我们需要对此进行单元测试,以确保所生成的查询在各种情况下都是正确的。测试它的一种方法(可能是更好的方法)是通过在最后检查休眠条件并模拟数据库交互来正确创建休眠条件。但是,这是不理想的,因为它首先是一种作弊行为(…