英文:
How to test for error paths and corner cases in JUnit?
问题
以下是您的翻译内容:
我有一段代码,我必须为它编写JUnit测试。我已经为正常情况编写了测试,但我还必须为边缘情况和错误路径编写测试。你能帮我找到解决方案吗?
public String reverseWords(String input) {
String oneOrMoreSpaces = "\\s+";
String[] words = input.split(oneOrMoreSpaces);
String completeAnagram = "";
for (int i = 0; i < words.length; i++) {
char[] symbol = words[i].toCharArray();
char newSymbolSequence;
int j = symbol.length - 1, k = 0;
while (k < j) {
if (!Character.isAlphabetic(symbol[k]))
k++;
else if (!Character.isAlphabetic(symbol[j]))
j--;
else {
newSymbolSequence = symbol[k];
symbol[k] = symbol[j];
symbol[j] = newSymbolSequence;
k++;
j--;
}
}
completeAnagram = new String(symbol);
}
return completeAnagram;
}
英文:
I have code and I have to write JUnit tests for it. I already wrote test for happy path, but I have to write tests for corner cases and error paths. Can you help me with finding solution pls.
public String reverseWords(String input) {
String oneOrMoreSpaces = "\\s+";
String[] words = input.split(oneOrMoreSpaces);
String completeAnagram = "";
for (int i = 0; i < words.length; i++) {
char[] symbol = words[i].toCharArray();
char newSymbolSequence;
int j = symbol.length - 1, k = 0;
while (k < j) {
if (!Character.isAlphabetic(symbol[k]))
k++;
else if (!Character.isAlphabetic(symbol[j]))
j--;
else {
newSymbolSequence = symbol[k];
symbol[k] = symbol[j];
symbol[j] = newSymbolSequence;
k++;
j--;
}
}
completeAnagram = new String(symbol);
}
return completeAnagram;
}
答案1
得分: 5
这感觉像是一个作业问题。尽管练习很不错!代码似乎包含(至少)一个错误,让人很想看看你在哪个步骤能发现这个错误。
解决这类问题的一些指南:
-
只有在你知道功能应该是什么的情况下,你才能考虑测试一个方法。这里的简短回答似乎是“给定一个句子,生成每个单词都颠倒的句子”,但这可能需要一些改进。
-
一旦你认为你知道方法应该做什么,你可以想出一系列的示例输入和输出。这些最终将成为你的测试用例。
-
通过提供示例,你可以批判性地寻找复杂的(“角落”?)情况。如果没有单词会发生什么?字母是否应该与标点符号一样对待?颠倒一个只有一个字母的单词会有什么影响?你不需要任何代码,只需要理解应用领域。每个问题可能会产生更多的示例。
-
一旦你有足够的示例,你可以为它们创建测试用例。参数化测试似乎是一个自然的选择。
-
在运行基于需求的测试用例之后,您可以分析实现。每一行/分支都有覆盖吗?确实有一个测试用例在代码中间执行
else if
分支吗?如果有未执行的代码,请返回到需求,并考虑哪个示例需要此分支。然后添加该示例,直到覆盖所有情况。 -
一旦你实现了完全的分支覆盖,你可以尝试有意引入代码中的小错误。如果你将
<
替换为<=
,你的其中一个示例是否会揭示这个错误?如果不是,请添加这样的示例!
如果你想了解更多信息,可以搜索分类分区(第3步),分支覆盖(第5步)和突变覆盖(第6步)。关于这一点,你可以查阅我们的开放式在线书籍《软件测试:从理论到实践》,其中包括视频、幻灯片和练习。享受吧!
英文:
This feels like a homework question. The exercise is nice enough, though! The code seems to contain (at leats) one fault, making it interesting to see at which step you can discover this.
Some guidelines for addressing this type of problem:
-
You can only think about testing a method if you know what the functionality is supposed to be. The short answer here seems to be given a sentence, produce the sentence with each word reversed, but this could use some improvement.
-
Once you think you know what the method should do, you can come up with a series of example inputs and outputs. These will eventually be your test cases.
-
By producing examples, you can critically look for complicated ("corner"?) cases. What happens if there are no words? Should letters be treated the same as punctuation? What is the effect of reversing a one-letter word? You don't need any code for this, just an understanding of the application domain. Each of these questions may give rise to more examples.
-
Once you have enough examples, you can create test cases for them. Parameterized tests seem a natural fit.
-
With your requirements-driven test cases up and running, you can then analyze the implementation. Is every line / branch covered? Is there indeed a test case that exercises the
else if
branch in the middle of the code? If there is code that is not executed, go back to the requirements, and think which example would require this branch. Then add that example, until you have full coverage. -
Once you have full branch coverage, you may try and deliberately introduce small mistakes in the code. If you replace a
<
by a<=
, will one of your examples reveal this as a bug? If not, add such an example!
If you want to learn more, look for category-partition (step 3), branch coverage (step 5), and mutation coverage (step 6). For this, you can check out our open access online book Software Testing: From Theory to Practice, which includes videos, slides, and exercises. Enjoy!
答案2
得分: 0
如果您需要在异常情况下进行验证,可以使用 Junit 的 @test(expected=您的异常类名) 注解。
示例:
// obj 需要在类中进行初始化
@Test(expected=NullPointerException.class)
public void testNullPonterException(){
String val = obj.reverseWords(null);
}
否则,当您需要验证异常的其他属性时,可以使用 ExpectedException 规则。
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@Test
public void whentestNullPonterExceptionThrown_thenRuleIsApplied() {
exceptionRule.expect(NullPointerException.class);
exceptionRule.expectMessage("Invalid Input");
String val = obj.reverseWords(null);
}
英文:
If you need to verify on exceptions you can use Junit @test(expected=Yor exception)
ex :
obj need to be initialized in the class.
@Test(expected=NullPointerException.class)
public void testNullPonterException(){
String val = obj.reverseWords(null);
}
Otherwise you When you need to verify some other properties of the exception, we can use the ExpectedException rule.
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@Test
public void whentestNullPonterExceptionThrown_thenRuleIsApplied() {
exceptionRule.expect(NullPointerException.class);
exceptionRule.expectMessage("Invalid Input");
String val = obj.reverseWords(null);
}
答案3
得分: 0
常见的错误和边界情况是输入为 null
或空字符串。
英文:
Common error and edge cases are that the input is null
or an empty String.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论