JavaRush /Java 博客 /Random-ZH /JUnit for JavaRush 或一些有关在家测试的信息。
Sdu
第 17 级

JUnit for JavaRush 或一些有关在家测试的信息。

已在 Random-ZH 群组中发布
厌倦了在控制台中多次输入测试数据来检查您的任务?欢迎来到这只猫,我会告诉你你能用它做什么。 本材料的最终目标是自动启动使用各种参数解决的任务并检查结果,而无需更改其源代码。正如您可能已经从标题中了解到的,在这个相当简单的问题上我们的主要助手将是 JUnit。如果你还没有听说过 单元测试单元测试,我建议你休息一下并熟悉这些概念,幸运的是互联网上有足够的信息。不,你不想吗?好吧,我认为这不会成为理解正在发生的事情的大问题。毕竟,您知道测试和一般测试是什么吗?每次启动任务时,您都会执行此操作,输入初始数据并将结果与​​您期望看到的结果进行比较。
你好,世界JUnit!
什么是 JUnit?在该项目的 官方网站上我们可以看到以下描述:
JUnit 是一个用于编写可重复测试的简单框架。它是单元测试框架的 xUnit 架构的一个实例。
对于我们来说,这意味着能够编写专门设计的类,其方法将与我们的程序交互,将结果与参考结果进行比较,如果不匹配则通知我们。要理解原理,请考虑一个简单的例子。假设我们有一个辅助类,其中一个方法接受两个 int类型的变量并返回它们的和: JUnit for JavaRush 或一些有关在家测试的信息。 - 1 这是我们将尝试测试的功能。幸运的是,我们最喜欢的 IDEA 已经具备了快速创建测试所需的一切,我们所需要做的就是将光标放在类声明行中,按“Alt + Enter”并在上下文菜单中选择“创建测试”:指定 JUnit for JavaRush 或一些有关在家测试的信息。 - 2 位置后你应该创建一个测试,IDEA建议选择一个测试库(在本材料中我使用JUnit4;为了将库类连接到项目,你需要单击“Fix”按钮)、要测试的方法和其他选项。 JUnit for JavaRush 或一些有关在家测试的信息。 - 3 IDE 将创建一个测试类模板: ClassName = TestClassName + "Test" MethodName = "test" + TestMethodName JUnit for JavaRush 或一些有关在家测试的信息。 - 4 我们只需要填写方法体即可。 JUnit 提供的所谓“断言”方法将对此有所帮助。简单来说,他们的工作是这样的:预期结果和调用被测方法的结果都传递给 .assert* 方法;为了方便起见,您可以添加解释性消息作为第一个参数。如果测试期间参数不匹配,您将收到通知。您可以像常规类一样启动测试类来执行,我更喜欢使用组合键 Ctrl+Shift+F10 JUnit for JavaRush 或一些有关在家测试的信息。 - 5
让我们指定任务
从理论上讲,一切都是简单而美丽的,但在所提出的示例的背景下,这并不是真正必要的;我们可以相信计算机会将两个数字相加。我们更感兴趣的是 JavaRush 学生解决的实际问题会如何发展;例如,我建议学习深受喜爱的 level05.lesson12.bonus03。
/* 算法问题 编写一个程序: 1. 从控制台输入数字 N > 0 2. 然后从控制台输入 N 个数字 3. 显示输入的 N 个数字中的最大值。*/
我们需要编写三个测试,分别针对正数、负数和混合集。
越往森林深处...
这里有一些惊喜等待着我们: public class UtilApp { public static void main(String[] args) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); //напишите здесь ваш code int n; int maximum; /* Конечно же я не буду размещать решение задачи ;) Код приведенный тут переработан для наглядности, и не в коем случае не означает что он должен присутствовать в "правильном решении" */ System.out.println(maximum); } }
  • 程序逻辑放在main()方法中
  • 源数据不会传递给方法,而是从键盘输入。
  • main()方法不返回结果,而是将其输出到控制台。
如果第一点不是特别有问题(我们可以照常调用main()方法),那么接下来的两点就迫使我们深入主题,绞尽脑汁。我找到了解决该问题的几种方法:
  1. 将查找最大值的逻辑移至单独的方法中。
    • 优点:重构方面的正确方法
    • 缺点:程序变得过多的代码、不必要的结构,至少添加了一个数组或 ArrayList(取决于品味和颜色......)。仅测试寻找最大值的机制;不检查数据输入和输出。
  2. 为 System.in/System.out 编写包装器。
    • 优点:我们不使用第三方库。
    • 缺点:该路径不适合初学者。测试实现的相对复杂性;测试中的代码量可能大于正在测试的任务中的代码量。
  3. 使用额外的库进行测试。
    • 优点:测试中的代码干净,编写测试相对容易。被测类的源代码没有改变。
    • 缺点:需要将第三方库连接到项目。
说实话,我最喜欢第三个选项,所以让我们尝试实现它。
系统规则
经过简短的搜索,我进入了页面 http://stefanbirkner.github.io/system-rules/,我立即意识到这就是我所需要的。
用于测试使用 java.lang.System 的代码的 JUnit 规则集合。
那么, 让我们下载这个库。下载系统规则发挥作用所需的 Commons IO库。我们将两个库连接到我们的项目(文件 -> 项目结构 -> 库 -> + -> Java)并开始雕刻:启动后,我们的任务要求您从控制台输入 N+1 个数字,其中第一个数字告诉您有多少人会追随他。在系统规则中,TextFromStandardInputStream类用于这些目的。最初,我们需要将这种类型的字段添加到我们的测试类中,并用@Rule注释标记它: @Rule public final TextFromStandardInputStream systemInMock = emptyStandardInputStream(); 然后,直接在测试方法中我们指示必要的数据: systemInMock.provideText("4\n2\n6\n1\n3\n"); 可以看到,数字以文本形式传输,并用连字符“\n”分隔。基于此,结果 N 将等于 4,我们将从数字 {2, 6, 1, 3} 中寻找最大值。接下来,我们需要创建被测试类的实例并调用 main() 方法。我们的程序从systemInMock读取数据,处理它并打印结果,我们所要做的就是读取它并与标准进行比较。为此,系统规则为我们提供了 StandardOutputStreamLog 类。我们添加一个指定类型的字段: @Rule public final StandardOutputStreamLog log = new StandardOutputStreamLog(); 可以使用 .getLog() 方法读取打印的数据,同时需要考虑到换行符的存在,最终的选项可以是这样的: assertEquals("{2, 6, 1, 3}, max = 6", "6", log.getLog().trim()); // or assertEquals("{2, 6, 1, 3}, max = 6", "6\r\n", log.getLog()); 在测试之间,为了避免数据分层,需要清除日志 log.clear(); 我的测试类全文: import org.junit.Rule; import org.junit.Test; import org.junit.contrib.java.lang.system.StandardOutputStreamLog; import org.junit.contrib.java.lang.system.TextFromStandardInputStream; import static org.junit.Assert.*; import static org.junit.contrib.java.lang.system.TextFromStandardInputStream.emptyStandardInputStream; public class UtilAppTest { @Rule public final TextFromStandardInputStream systemInMock = emptyStandardInputStream(); @Rule public final StandardOutputStreamLog log = new StandardOutputStreamLog(); @Test public void testAddition() throws Exception { systemInMock.provideText("4\n2\n6\n1\n3\n"); UtilApp utilApp = new UtilApp(); utilApp.main(new String[]{}); assertEquals("{2, 6, 1, 3}, max = 6", "6", log.getLog().trim()); systemInMock.provideText("5\n-100\n-6\n-15\n-183\n-1\n"); log.clear(); utilApp.main(new String[]{}); assertEquals("{-100, -6, -15, -183, -1}, max = -1", "-1", log.getLog().trim()); systemInMock.provideText("3\n2\n0\n-1\n"); log.clear(); utilApp.main(new String[]{}); assertEquals("{2, 0, -1}, max = 2", "2", log.getLog().trim()); } } 我们启动并享受。 -=!!! 重要!!!=- 本材料仅供参考;如果任务包中存在无关的类,我不保证在服务器上成功测试该任务。在向服务器发送验证任务之前,请删除所有无关的内容:不必要的文件、不必要的类、注释掉的代码。成功完成您创建的测试并不能保证服务器上的测试成功完成。我故意不去咀嚼理论材料:单元测试理论、JUnit注释、assert等等,所有材料都在文中提供的链接中。也许您有自己的测试任务的方法,我很乐意在评论中与您讨论。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION