当前位置: 首页 > 工具软件 > JUnit Max > 使用案例 >

junit junit_JUnit理论简介

翟嘉祥
2023-12-01

junit junit

您读过数学理论吗?

它通常读取如下内容:

对于所有a,b> 0满足以下条件:a + b> a和a + b> b

通常,这些语句更难以理解。

这种陈述有一些有趣的地方:它适用于相当大(在这种情况下为无限)集合的每个元素(或元素组合)。

将其与典型测试的陈述进行比较:

@Test
 public void a_plus_b_is_greater_than_a_and_greater_than_b(){
   int a = 2;
   int b = 3;
   assertTrue(a + b > a);
   assertTrue(a + b > b);
 }

这仅是关于我们所讨论的大集合中单个元素的陈述。 不太令人印象深刻。 当然,我们可以通过遍历测试(或使用参数化测试 )来解决此问题:

@Test
 public void a_plus_b_is_greater_than_a_and_greater_than_b_multiple_values() {
    List<Integer> values = Arrays.asList(1, 2, 300, 400000);
    for (Integer a : values)
      for (Integer b : values) {
         assertTrue(a + b > a);
         assertTrue(a + b > b);
      }
    }

当然,这仍然仅测试了一些值,但是也变得非常难看。 我们正在使用9行代码来测试数学家在一行中写的内容! 这种关系对于任何值a,b都应保持的要点在翻译中完全消失了。

但是仍然有希望: JUnit理论 。 让我们看看使用该漂亮工具的测试情况:

import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertTrue;

@RunWith(Theories.class)
public class AdditionWithTheoriesTest {

  @DataPoints
  public static int[] positiveIntegers() {
       return new int[]{
                        1, 10, 1234567};
  }

  @Theory
  public void a_plus_b_is_greater_than_a_and_greater_than_b(Integer a, Integer b) {
      assertTrue(a + b > a);
      assertTrue(a + b > b);
  }
}

使用JUnit理论,测试分为两个独立部分:提供数据点(即用于测试的值)的方法以及理论本身。 该理论看起来几乎像是一个测试,但是它具有不同的注释(@Theory)并且需要参数。 类中的理论将与数据点的每种可能组合一起执行。

这意味着,如果我们对测试主题有一个以上的理论,则只需声明数据点一次。 因此,让我们添加以下理论,这对于加法而言应该是正确的:a + b = b + a因此,我们将以下理论添加到我们的类@Theory中public void add_is_commutative(Integer a,Integer b){assertTrue(a + b == b + a); }

这就像一种魅力,并且可以开始看到它实际上也节省了一些代码,因为我们不重复数据点。 但是,我们仅使用正整数进行测试,而可交换属性应适用于所有整数! 当然,我们的第一个理论仍然只适用于正数

也有一个解决方案: 假设 。 假设您可以检查理论的先决条件。 如果对于给定的参数集不正确,则该理论将被跳过。 所以我们的测试现在看起来像这样:

@RunWith(Theories.class)
 public class AdditionWithTheoriesTest {

  @DataPoints
  public static int[] integers() {
     return new int[]{
                   -1, -10, -1234567,1, 10, 1234567};
  }

  @Theory
  public void a_plus_b_is_greater_than_a_and_greater_than_b(Integer a, Integer b) {
     Assume.assumeTrue(a >0 && b > 0 );
     assertTrue(a + b > a);
     assertTrue(a + b > b);
  }

  @Theory
  public void addition_is_commutative(Integer a, Integer b) {
     assertTrue(a + b == b + a);
  }
}

这使测试表现力很好。

将测试数据与测试/理论实现分开,除了简洁以外,还可以带来另一个积极的效果:您可能会开始考虑与实际测试内容无关的测试数据。

让我们做到这一点。 如果要测试采用整数参数的方法,那么哪些整数可能会引起问题? 这是我的建议:

@DataPoints
  public static int[] integers() {
     return new int[]{
                     0, -1, -10, -1234567,1, 10, 1234567, Integer.MAX_VALUE, Integer.MIN_VALUE};}

在我们的示例中,哪个当然会导致测试失败。 如果在Integer.MAX_VALUE中添加一个正整数,则会溢出! 因此,我们刚刚得知我们目前的理论是错误的! 是的,我知道这很明显,但是请看一下当前项目中的测试。 使用整数的所有测试是否都以MIN_VALUE,MAX_VALUE,0,正值和负值测试? 是的,是这样。

那更复杂的对象呢? 琴弦? 日期? 收藏? 还是领域对象? 使用JUnit Theories,您可以设置测试数据生成器一次,以创建所有容易产生问题的场景,然后使用这些理论在所有测试中重用这些场景。 这将使您的测试更具表现力,并提高发现错误的可能性。

参考:来自Java出现日历博客的JCG合作伙伴 Jens Schauder 对JUnit理论的介绍

翻译自: https://www.javacodegeeks.com/2013/12/introduction-to-junit-theories.html

junit junit

 类似资料: