ABAP UT(单元测试)

UT的重点是处理外部依赖(dependency),外部依赖主要是指当前需要测试的类里用到了其他类,Function Module或者是SQL;可能存在外部依赖的地方是类的属性,方法和方法参数。

处理外部依赖的做法之一是隔离(Isolation),让外部依赖返回我们需要的值从而达到测试的目的,常规做法是用接口(Interface)方法来封装外部依赖的逻辑,如果外部依赖本身是类,那也可以直接把这个类改写成接口。对于老的代码(Legacy Code),如果想做依赖隔离的话只能修改生产代码,所以新开发的代码应该尽量在有外部依赖地方使用接口来保证可测性,ABAP的代码检查(ATC)里有一项是类里所有的公有(Public)方法都需要写成接口方法,当然这只是建议,不是强制的。

UT用的接口可以是全局的,也可以局部的,局部的话是定义在类的Local部分。全局的好处是可以使用test double framework(动态创建实现类,并且可以指定方法返回值),局部的好处是不用定义全局对象,接口和测试的实现类(test double class)都在类的Local文件里定义和实现,测试类方法的返回值可以自己写逻辑指定。

定义好接口后,就是在测试环境里把接口的测试实例化对象“注入”到类里,常见做法是把测试用的接口都定义类的属性(需要是公有的或者有对应的外部调用方法),之后在测试环境中实例化(CONSTRUCTOR方法)测试类后进行“注入”,这样就实现了隔离(在生产环境下调用生产代码的逻辑,在测试环境里调用测试代码)。 Function Module除了可以使用接口封装外,也可以用Function Module的test double framework。

上面说的方法都是通过隔离外部依赖,自定义返回值来达到测试的目的,如果确定外部依赖的逻辑的话,也可以通过给“假数据”(mock data)的方法进行测试。比如如果知道外部依赖设计数据库交互,并且知道是哪些数据库表的话,可以用SQL test double(类cl_osql_test_environment)直接mock数据库表的数据,这样在测试环境中运行的话,会得到mock后的值,而不是实际数据库里的值。同样,如果确定外部依赖的类方法和Function Module的内部逻辑,也可以通过造“假数据”返回特定的值,但这种做法不是每个类方法和Function Module都能使用的,这时就要具体方法具体分析了。

总体来说隔离外部依赖更加常用,这种做法是不会执行外部依赖的代码的,所以可以保证可测性;而后面那种做法则会实际执行外部依赖代码,只不过我们了解其中的过程,通过造一些“假数据”来控制外部依赖返回的值,但不保证总是可行的。

总结一下:作为UT开发者,首先要关注外部依赖,然后进行相对应的处理;而作为生产代码开发者,如果为要保证代码的可测性,需要尽量把外部依赖封装成接口,不然后面想要补UT的话需要修改生产代码。

你可能感兴趣的:(ABAP,UT)