我正在考虑如何为我的项目编写测试。目前,测试结构如下:
RealClass
{
method1;
method2;
...
}
和完全相同的测试类结构:
TestClass {
testMethod1;
testMethod2;
...
}
但是,我不喜欢它,因为我在一种测试方法中放了太多的测试用例......
可能我应该使用这样的结构:
TestClass {
testMethod1Opt1;
testMethod1Opt2;
...
testMethod2Opt1;
...}
你是如何编写单元测试的?
public void testIsAppUser() {
// My (Artem`s Zinnatullin) uId
final long artemZinnatullinUId = 172672179;
try {
assertTrue(usersApi.isAppUser(artemZinnatullinUId));
} catch (Exception e) {
fail(e.getMessage());
}
// Pavel`s Durov uId
final long durovUId = 1;
try {
assertFalse(usersApi.isAppUser(durovUId));
} catch (Exception e) {
fail(e.getMessage());
}
// By default uId == current user`s (who has authorized) uId
try {
assertTrue(usersApi.isAppUser(null));
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testIsAppUser1() {
// My (Artem`s Zinnatullin) uId
final long artemZinnatullinUId = 172672179;
try {
assertTrue(usersApi.isAppUser(artemZinnatullinUId));
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testIsAppUser2() {
// Pavel`s Durov uId
final long durovUId = 1;
try {
assertFalse(usersApi.isAppUser(durovUId));
} catch (Exception e) {
fail(e.getMessage());
}
}
public void testIsAppUser3() {
// By default uId == current user`s (who has authorized) uId
try {
assertTrue(usersApi.isAppUser(null));
} catch (Exception e) {
fail(e.getMessage());
}
}
请给我建议。
答案 0 :(得分:2)
评论:
而不是try{} catch(){ fail() }
只需将throws Exception
添加到测试方法中。 JUnit会自动使测试失败和保留堆栈跟踪。这将使错误修复变得更加容易。
创建小型测试方法。这造成了名称问题:如何提出许多好名字?这里的解决方案是在逻辑测试之后命名测试,而不是它调用的方法。
如果要查看调用的方法,请使用代码覆盖率工具,如JaCoCo。
所以第一次测试应该被称为testIsArtemsZinnatullinAppUser()
。作为指导:每当您觉得需要评论来解释测试的内容时,测试名称是错误的。使用您在评论中写的任何内容来创建测试名称。
你应该进行较小测试的原因是JUnit会因第一个问题而停止。因此,如果您在一个测试用例中有20个测试而第3个测试失败,那么将无法运行17个测试。但这17项测试可能包含有价值的信息,有助于找出问题所在。
如果它们都成功了,那么这可能是一个特定的问题。如果许多测试失败,则问题必须出在共享代码中。
答案 1 :(得分:1)
构建测试的第二种方法要好得多。这样每种测试方法都会以不同的方式来破解方法,所以你不会遇到修复方法中的一个bug的情况,然后让测试失败一点(这样一个错误就会阻止你看到其他)。更重要的是,测试方法比测试方法映射到被测对象的方法要小且注意力集中。
另外,不要捕获异常,JUnit会为你做到这一点。将throws Exception
添加到每个测试方法的签名中。如果你想检查是否真的抛出异常,那么你可以在测试中捕获它,例如:
try {
objectUnderTest.doSomethingThatShouldThrowFooException();
fail("should've thrown an exception before getting here");
}
catch (FooException fooEx) {
// yay. my test passed
}
,但是:
的样板} catch (Exception e) {
fail(e.getMessage());
}
是不必要的。