我是否需要在使用 GWTTestCase 创建的每个单元测试方法前加上 'test' 前缀?
Do i need to prefix 'test' to every unit test method i create with GWTTestCase?
我正在学习如何在 GWT 中执行单元测试。所以我创建了一个 class 来扩展 GWTTestCase class 并在其中编写测试方法。
问题是,如果我不在这个 class(public 或私有)中的一个函数前面加上 'test' 这个词的前缀,除了继承的 'getModuleName' 方法,我得到一个 'initialization error'。
现在我做错了什么或者添加这个前缀是规则吗?如果它真的是一个规则,这是什么原因?
public class hellotest extends GWTTestCase{
@Override
public String getModuleName() {
// TODO Auto-generated method stub
return "hellopackage.Hello1";
}
public void test()
{
assertTrue(true);
}
public void test2()
{
assertTrue(true);
}
public void notTest3() //Produces initialization error
{
assertTrue(true);
}
}
'initialization error' 的堆栈跟踪:-
// Compiled from Filter.java (version 1.5 : 49.0, super bit)
public abstract class org.junit.runner.manipulation.Filter {
// Field descriptor #14 Lorg/junit/runner/manipulation/Filter;
public static final org.junit.runner.manipulation.Filter ALL;
// Method descriptor #16 ()V
// Stack: 1, Locals: 1
public Filter();
0 aload_0 [this]
1 invokespecial java.lang.Object() [1]
4 return
Line numbers:
[pc: 0, line: 17]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: org.junit.runner.manipulation.Filter
// Method descriptor #22 (Lorg/junit/runner/Description;)Lorg/junit/runner/manipulation/Filter;
// Stack: 3, Locals: 1
public static org.junit.runner.manipulation.Filter matchMethodDescription(org.junit.runner.Description desiredDescription);
0 new org.junit.runner.manipulation.Filter [2]
3 dup
4 aload_0 [desiredDescription]
5 invokespecial org.junit.runner.manipulation.Filter(org.junit.runner.Description) [3]
8 areturn
Line numbers:
[pc: 0, line: 48]
Local variable table:
[pc: 0, pc: 9] local: desiredDescription index: 0 type: org.junit.runner.Description
// Method descriptor #26 (Lorg/junit/runner/Description;)Z
public abstract boolean shouldRun(org.junit.runner.Description arg0);
// Method descriptor #28 ()Ljava/lang/String;
public abstract java.lang.String describe();
// Method descriptor #30 (Ljava/lang/Object;)V
// Stack: 2, Locals: 3
public void apply(java.lang.Object child) throws org.junit.runner.manipulation.NoTestsRemainException;
0 aload_1 [child]
1 instanceof org.junit.runner.manipulation.Filterable [4]
4 ifne 8
7 return
8 aload_1 [child]
9 checkcast org.junit.runner.manipulation.Filterable [4]
12 astore_2 [filterable]
13 aload_2 [filterable]
14 aload_0 [this]
15 invokeinterface org.junit.runner.manipulation.Filterable.filter(org.junit.runner.manipulation.Filter) : void [5] [nargs: 2]
20 return
Line numbers:
[pc: 0, line: 93]
[pc: 7, line: 94]
[pc: 8, line: 96]
[pc: 13, line: 97]
[pc: 20, line: 98]
Local variable table:
[pc: 0, pc: 21] local: this index: 0 type: org.junit.runner.manipulation.Filter
[pc: 0, pc: 21] local: child index: 1 type: java.lang.Object
[pc: 13, pc: 21] local: filterable index: 2 type: org.junit.runner.manipulation.Filterable
// Method descriptor #38 (Lorg/junit/runner/manipulation/Filter;)Lorg/junit/runner/manipulation/Filter;
// Stack: 5, Locals: 3
public org.junit.runner.manipulation.Filter intersect(org.junit.runner.manipulation.Filter second);
0 aload_1 [second]
1 aload_0 [this]
2 if_acmpeq 12
5 aload_1 [second]
6 getstatic org.junit.runner.manipulation.Filter.ALL : org.junit.runner.manipulation.Filter [6]
9 if_acmpne 14
12 aload_0 [this]
13 areturn
14 aload_0 [this]
15 astore_2 [first]
16 new org.junit.runner.manipulation.Filter [7]
19 dup
20 aload_0 [this]
21 aload_2 [first]
22 aload_1 [second]
23 invokespecial org.junit.runner.manipulation.Filter(org.junit.runner.manipulation.Filter, org.junit.runner.manipulation.Filter, org.junit.runner.manipulation.Filter) [8]
26 areturn
Line numbers:
[pc: 0, line: 105]
[pc: 12, line: 106]
[pc: 14, line: 108]
[pc: 16, line: 109]
Local variable table:
[pc: 0, pc: 27] local: this index: 0 type: org.junit.runner.manipulation.Filter
[pc: 0, pc: 27] local: second index: 1 type: org.junit.runner.manipulation.Filter
[pc: 16, pc: 27] local: first index: 2 type: org.junit.runner.manipulation.Filter
// Method descriptor #16 ()V
// Stack: 2, Locals: 0
static {};
0 new org.junit.runner.manipulation.Filter [9]
3 dup
4 invokespecial org.junit.runner.manipulation.Filter() [10]
7 putstatic org.junit.runner.manipulation.Filter.ALL : org.junit.runner.manipulation.Filter [6]
10 return
Line numbers:
[pc: 0, line: 21]
Inner classes:
[inner class info: #2 org/junit/runner/manipulation/Filter, outer class info: #0
inner name: #0, accessflags: 8 static],
[inner class info: #7 org/junit/runner/manipulation/Filter, outer class info: #0
inner name: #0, accessflags: 0 default],
[inner class info: #9 org/junit/runner/manipulation/Filter, outer class info: #0
inner name: #0, accessflags: 8 static]
}
GWTTestCase 扩展了 JUnit 3 TestCase,在 JUnit 3 中,测试方法确实应该以 test
.
开头
原因是 JUnit 的设计方式:它在测试用例中搜索以 test
开头的 public void 方法。这是在 Java 5 之前完成的,当时注释还不存在。如今,JUnit 4(和 5)使用注解 "flag" 测试方法。
除了已经回答的问题"is it technically required";你也可以考虑约定。
我见过的大多数单元测试...都是从 testWhatever() 开始的。
要点是:命名 是编写干净、可读、可维护代码的核心要素。生产代码也是如此;但是,很多人认为您的测试代码甚至比生产代码更重要……因此编写干净、可读、可维护的测试代码是软件开发的重要组成部分。
换句话说:可能大多数人都希望测试方法以 "test" 开头。但最后:关键是名称说明了实际测试的内容;所以 test(), test1(), ... 等等对于测试方法来说真的是非常糟糕的名字。
(附注:如果您有兴趣编写好的测试,请查看 assertThat;并且忘记使用任何其他断言调用)。
我正在学习如何在 GWT 中执行单元测试。所以我创建了一个 class 来扩展 GWTTestCase class 并在其中编写测试方法。
问题是,如果我不在这个 class(public 或私有)中的一个函数前面加上 'test' 这个词的前缀,除了继承的 'getModuleName' 方法,我得到一个 'initialization error'。
现在我做错了什么或者添加这个前缀是规则吗?如果它真的是一个规则,这是什么原因?
public class hellotest extends GWTTestCase{
@Override
public String getModuleName() {
// TODO Auto-generated method stub
return "hellopackage.Hello1";
}
public void test()
{
assertTrue(true);
}
public void test2()
{
assertTrue(true);
}
public void notTest3() //Produces initialization error
{
assertTrue(true);
}
}
'initialization error' 的堆栈跟踪:-
// Compiled from Filter.java (version 1.5 : 49.0, super bit)
public abstract class org.junit.runner.manipulation.Filter {
// Field descriptor #14 Lorg/junit/runner/manipulation/Filter;
public static final org.junit.runner.manipulation.Filter ALL;
// Method descriptor #16 ()V
// Stack: 1, Locals: 1
public Filter();
0 aload_0 [this]
1 invokespecial java.lang.Object() [1]
4 return
Line numbers:
[pc: 0, line: 17]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: org.junit.runner.manipulation.Filter
// Method descriptor #22 (Lorg/junit/runner/Description;)Lorg/junit/runner/manipulation/Filter;
// Stack: 3, Locals: 1
public static org.junit.runner.manipulation.Filter matchMethodDescription(org.junit.runner.Description desiredDescription);
0 new org.junit.runner.manipulation.Filter [2]
3 dup
4 aload_0 [desiredDescription]
5 invokespecial org.junit.runner.manipulation.Filter(org.junit.runner.Description) [3]
8 areturn
Line numbers:
[pc: 0, line: 48]
Local variable table:
[pc: 0, pc: 9] local: desiredDescription index: 0 type: org.junit.runner.Description
// Method descriptor #26 (Lorg/junit/runner/Description;)Z
public abstract boolean shouldRun(org.junit.runner.Description arg0);
// Method descriptor #28 ()Ljava/lang/String;
public abstract java.lang.String describe();
// Method descriptor #30 (Ljava/lang/Object;)V
// Stack: 2, Locals: 3
public void apply(java.lang.Object child) throws org.junit.runner.manipulation.NoTestsRemainException;
0 aload_1 [child]
1 instanceof org.junit.runner.manipulation.Filterable [4]
4 ifne 8
7 return
8 aload_1 [child]
9 checkcast org.junit.runner.manipulation.Filterable [4]
12 astore_2 [filterable]
13 aload_2 [filterable]
14 aload_0 [this]
15 invokeinterface org.junit.runner.manipulation.Filterable.filter(org.junit.runner.manipulation.Filter) : void [5] [nargs: 2]
20 return
Line numbers:
[pc: 0, line: 93]
[pc: 7, line: 94]
[pc: 8, line: 96]
[pc: 13, line: 97]
[pc: 20, line: 98]
Local variable table:
[pc: 0, pc: 21] local: this index: 0 type: org.junit.runner.manipulation.Filter
[pc: 0, pc: 21] local: child index: 1 type: java.lang.Object
[pc: 13, pc: 21] local: filterable index: 2 type: org.junit.runner.manipulation.Filterable
// Method descriptor #38 (Lorg/junit/runner/manipulation/Filter;)Lorg/junit/runner/manipulation/Filter;
// Stack: 5, Locals: 3
public org.junit.runner.manipulation.Filter intersect(org.junit.runner.manipulation.Filter second);
0 aload_1 [second]
1 aload_0 [this]
2 if_acmpeq 12
5 aload_1 [second]
6 getstatic org.junit.runner.manipulation.Filter.ALL : org.junit.runner.manipulation.Filter [6]
9 if_acmpne 14
12 aload_0 [this]
13 areturn
14 aload_0 [this]
15 astore_2 [first]
16 new org.junit.runner.manipulation.Filter [7]
19 dup
20 aload_0 [this]
21 aload_2 [first]
22 aload_1 [second]
23 invokespecial org.junit.runner.manipulation.Filter(org.junit.runner.manipulation.Filter, org.junit.runner.manipulation.Filter, org.junit.runner.manipulation.Filter) [8]
26 areturn
Line numbers:
[pc: 0, line: 105]
[pc: 12, line: 106]
[pc: 14, line: 108]
[pc: 16, line: 109]
Local variable table:
[pc: 0, pc: 27] local: this index: 0 type: org.junit.runner.manipulation.Filter
[pc: 0, pc: 27] local: second index: 1 type: org.junit.runner.manipulation.Filter
[pc: 16, pc: 27] local: first index: 2 type: org.junit.runner.manipulation.Filter
// Method descriptor #16 ()V
// Stack: 2, Locals: 0
static {};
0 new org.junit.runner.manipulation.Filter [9]
3 dup
4 invokespecial org.junit.runner.manipulation.Filter() [10]
7 putstatic org.junit.runner.manipulation.Filter.ALL : org.junit.runner.manipulation.Filter [6]
10 return
Line numbers:
[pc: 0, line: 21]
Inner classes:
[inner class info: #2 org/junit/runner/manipulation/Filter, outer class info: #0
inner name: #0, accessflags: 8 static],
[inner class info: #7 org/junit/runner/manipulation/Filter, outer class info: #0
inner name: #0, accessflags: 0 default],
[inner class info: #9 org/junit/runner/manipulation/Filter, outer class info: #0
inner name: #0, accessflags: 8 static]
}
GWTTestCase 扩展了 JUnit 3 TestCase,在 JUnit 3 中,测试方法确实应该以 test
.
原因是 JUnit 的设计方式:它在测试用例中搜索以 test
开头的 public void 方法。这是在 Java 5 之前完成的,当时注释还不存在。如今,JUnit 4(和 5)使用注解 "flag" 测试方法。
除了已经回答的问题"is it technically required";你也可以考虑约定。
我见过的大多数单元测试...都是从 testWhatever() 开始的。
要点是:命名 是编写干净、可读、可维护代码的核心要素。生产代码也是如此;但是,很多人认为您的测试代码甚至比生产代码更重要……因此编写干净、可读、可维护的测试代码是软件开发的重要组成部分。
换句话说:可能大多数人都希望测试方法以 "test" 开头。但最后:关键是名称说明了实际测试的内容;所以 test(), test1(), ... 等等对于测试方法来说真的是非常糟糕的名字。
(附注:如果您有兴趣编写好的测试,请查看 assertThat;并且忘记使用任何其他断言调用)。