中国建设工程造价管理协会网站,微信官方小程序商城,大型网站开发收费,wordpress 侧边悬浮块调试是“以交互方式运行程序/方法#xff0c;在每个语句后中断执行流程并显示……的过程。”简而言之#xff0c;它是一种非常有用的技术……对于一个糟糕的程序员而言。 或仍然在用C编写过程代码的老程序员。面向对象的程序员从不调试其代码-他们编写单元测试。 我的意思是在每个语句后中断执行流程并显示……的过程。”简而言之它是一种非常有用的技术……对于一个糟糕的程序员而言。 或仍然在用C编写过程代码的老程序员。面向对象的程序员从不调试其代码-他们编写单元测试。 我的意思是单元测试是一种完全替代调试的技术。 如果需要调试则设计很糟糕 。 The Revenant2015作者Alejandro G.Iñárritu 假设我是一个糟糕的命令式程序程序员这是我的Java代码 class FileUtils {public static IterableString readWords(File f) {String text new String(Files.readAllBytes(Paths.get(f)),UTF-8);SetString words new HashSet();for (String word : text.split( )) {words.add(word);}return words;}
} 此静态实用程序方法读取文件内容然后在其中找到所有唯一的单词。 很简单 但是如果它不起作用我们该怎么办 假设这是文件 We know what we are,
but know not what we may be. 从中我们得到以下单词列表 We
know
what
we
are,\n
but
not
may
be\n 现在这对我而言似乎不正确……那么下一步是什么 文件读取无法正常工作或拆分中断。 让我们调试吧 让我们通过输入为它提供文件并逐步进行操作跟踪并观察变量。 我们将找到该错误并进行修复。 但是当出现类似问题时我们将不得不再次调试 这就是单元测试应该避免的 。 我们应该一次创建一个单元测试以重现该问题。 然后我们解决问题并确保测试通过。 这就是我们节省解决问题投资的方式。 我们不会再修复它因为它不会再发生。 我们的测试将阻止它的发生。 如果您认为调试变得更快更轻松请考虑一下代码的质量 但是只有在创建单元测试很容易的情况下所有这些方法才有效。 如果困难的话我会懒得做。 我将调试并解决问题。 在此特定示例中创建测试是相当昂贵的过程。 我的意思是单元测试的复杂度会很高。 我们必须创建一个临时文件用数据填充它运行该方法然后检查结果。 为了弄清楚到底发生了什么以及漏洞在哪里我必须创建一些测试。 为了避免代码重复我还必须创建一些补充实用程序来帮助我创建该临时文件并用数据填充它。 这是很多工作。 好吧也许不是“很多”而是经过了数分钟的调试。 因此如果您认为调试更快更轻松请考虑一下代码的质量。 我敢打赌它有很多重构的机会就像上面示例中的代码一样。 这是我将如何修改它。 首先我将其转换为一个类因为实用程序静态方法是一种不好的做法 class Words implements IterableString {private final File file;Words(File src) {this.file src;}Overridepublic IteratorString iterator() {String text new String(Files.readAllBytes(Paths.get(this.file)),UTF-8);SetString words new HashSet();for (String word : text.split( )) {words.add(word);}return words.iterator();}
} 看起来已经更好了但是复杂性仍然存在。 接下来我将其分解为较小的类 class Text {private final File file;Text(File src) {this.file src;}Overridepublic String toString() {return new String(Files.readAllBytes(Paths.get(this.file)),UTF-8);}
}
class Words implements IterableString {private final String text;Words(String txt) {this.text txt;}Overridepublic IteratorString iterator() {SetString words new HashSet();for (String word : this.text.split( )) {words.add(word);}return words.iterator();}
} 您现在怎么看 为Words类编写测试是一项非常简单的任务 import org.junit.Test;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
public class WordsTest {Testpublic void parsesSimpleText() {assertThat(new Words(How are you?),hasItems(How, are, you));}
} 那花了多少时间 少于一分钟。 我们不需要创建一个临时文件并向其中加载数据因为Words类对文件没有任何作用。 它只是解析输入的字符串并在其中找到唯一的单词。 现在由于测试很小我们可以轻松创建更多测试因此很容易修复。 例如 import org.junit.Test;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
public class WordsTest {Testpublic void parsesSimpleText() {assertThat(new Words(How are you?),hasItems(How, are, you));}Testpublic void parsesMultipleLines() {assertThat(new Words(first line\nsecond line\n),hasItems(first, second, line));}
} 我的观点是当编写单元测试的时间远远大于单击那些“ Trace-In / Trace-Out”按钮所花费的时间时必须进行调试。 这是合乎逻辑的。 我们都很懒惰想要快速简便的解决方案。 但是调试会浪费时间并浪费能量。 它可以帮助我们发现问题但并不能阻止它们再次出现。 当我们的代码是需要调试的程序和算法当代码是所有的目标应该如何实现的而不是我们的目标是什么 。 再次参见上面的示例。 第一个静态方法是关于我们如何读取文件解析文件以及查找单词的所有方法。 它甚至被命名为readWords() 一个动词 。 相反第二个例子是关于将要实现的。 它可以是文件的Text 也可以是Text的Words 都是名词 。 我相信在干净的面向对象编程中没有调试的地方。 只有单元测试 翻译自: https://www.javacodegeeks.com/2016/11/are-you-still-debugging.html