csdn上第一篇技术blog,写些什么呢?由于正在等待测试的结果,那就分享一下Java的测试心得吧!
由于测试毕竟不是本职工作,对于一个Java软件开发工程师而言,我个人觉得,需要注意以下几点。
1.强烈建议Java软件开发工程师在有余力的情况下自己对重要的功能点写单元测试,尤其是逻辑单元的单元测试尤为重要。为什么呢?目前,我觉得主要原因是对于接口不变的单元测试,是可以回归的。可以通过这些单元测试保证程序修改后的逻辑正确性和边界条件的一致性;
对于Java的单元测试,主要是使用JUnit,目前较为流行的版本是4.4。使用JUnit较为方便的地方是,可以通过使用Annotation,将一个一个的单元测试写在一个一个的方法中,不用给每个单元测试都写一个Main方法。一个简单的示例:
public class AllTest {
@Before
public setUp() {
System.out.println("每次运行一个单元测试之前,都会运行此方法");
}
@After
public tearDown() {
System.out.println("每次运行完成一个单元测试,无论成功与否,都会运行此方法");
}
@Test
public test1() {
System.out.println("第一个单元测试");
}
@Test
public test2() {
System.out.println("第二个单元测试");
}
@Test
public test3() {
System.out.println("第三个单元测试");
}
}
JUnit还可以将多个单元测试类组合成一个TestSuit,一起测试,如:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses( { AllTest1.class, AllTest2.class, AllTest3.class } )
public class AllTests {
//这里什么也不用写
}
单元测试有两个比较好用的Mock集合,一个是EasyMock,一个是easymockclassextension。这两个类都可以模拟已有的接口(EasyMock)和类(easymockclassextension),对于那些接口的真实的类,需要繁琐的配置和很多依赖的情况下,建议使用它们。由于此类教程较多,在此不再多说。只是有一点需要提一下,就是,在连接数据库之类的类测试时,或者是即使是Mock也要实现较为复杂的功能时,建议自己写一个Mock类。如:
public interface BaseManager {
public void start();
public Object doCommand1();
public Object doCommand2();
public void end();
}
public class MockManager {
public void start() {
//start
}
public Object doCommand1() {
//完成该动作,可以返回特定的值
return new Object();
}
public doCommand2() {
//完成该动作,可以为抛出异常,
throw new RuntimeException();
}
public void end() {
//end
}
}
然后,在需要测试的地方,可以BaseManager manager = new MockManager();使用MockManager进行测试。
当我们测试时,尽量保证“测试类”和“被测试的类”在同一个包中,这样,包访问的属性和方法就可以被“测试类”访问到(建议使用Maven组织代码)。当需要访问不在同一个包中需要"被测试的类"访问包访问级别的属性和方法或者需要访问”被测试的类“的私有属性和方法时,可如下操作:
public class SomeManager {
private Object someManagerObject;
public void start() {
}
private Object doCommand(String arg) {
return new Object();
}
public void end() {
}
}
void someFunction() {
SomeManager manager = new SomeManager();
manager.start();
Field someManagerObjectField = null;
try {
someManagerObjectField = SomeManager.class.getDeclaredField("someManagerObject");
}
catch (Exception e) {
//记录日志或打印输出
}
Method doCommandMethod = null;
try {
doCommandMethod = SomeManager.class.getDeclaredMethod("doCommand", new Class[] { String.class });
}
catch (Exception e) {
//记录日志或打印输出
}
//此句很重要
//设置someManagerObjectField不检测Java语言访问检测
someManagerObjectField.setAccessible(true);
doCommandMethod.setAccessible(true);
Object object;
try {
object= /*这里如果为特殊类型,需要进行类型强制转换(Object)*/ someManagerObjectField .get(manager);
}
catch (Exception e) {
//记录日志或打印输出
}
//这里可以使用object了。
try {
doCommandMethod.invoke(manager, new Object[] {"String arg"});
}
catch (Exception e) {
//记录日志或打印输出
}
//方法已经调用了
}