我尝试过单元测试,我不是一个大粉丝; 它更多的是负担而不是恩惠.那么我应该对这个简单的2D点类进行哪些测试呢?
public class Point{
int x;
int y;
public Point(int px, int py) {
x = px;
y = py;
}
public double distanceTo(Point other) {
// Pythagorean theorem
}
public ArrayList<Point> lineTo(Point other) {
// Bresenham's line algorithm. The same thing I've
// implemented a dozen times in differnt languages
// and can type from memory....
}
}
Run Code Online (Sandbox Code Playgroud)
每种方法需要多少次测试?另一点可以与第一个或同一个四个象限中的一个位于同一位置,或者为空.那么每种方法有六个单元测试吗?
有可能让代码如此简单明了,以至于单元测试提供的价值很小,以至于它们不值得吗?
(到目前为止的响应是:应该为任何可以为null的参数,可以作为对象本身的任何参数(即this.distanceTo(this)),任何可能导致溢出的参数以及任何可能导致溢出的参数编写测试可能会导致浮点精度损失.至少有四件事要写测试.)
不,即使你称之为"简单代码",也可能犯错误.
您必须运行一次方法才能知道它们有效,对吧?将该呼叫作为单元测试捕获并以自动方式运行它有什么问题?
如果您同意这一点,那么值得讨论该单位将为您提供的所有其他好处:
至于你的距离法,当你谈到"四象限"时,我不知道你在想什么(是的,我知道那些是什么).这不是测试所必需的.
但是,是的,您应该测试以显示传入null Point时会发生什么(如果您抛出NPE?其他一些异常?默默地返回零?); 传递与目标相同的点,以确保您获得一个小的(希望为零)距离.如果由于浮点表示而变小,会发生什么?你准备好了吗?如果你传入一个非常大的点怎么办?会有溢出问题吗?你的方法可能很天真,足以计算组件平方和的平方根.因此,当你对一个非常大的数字进行平方,结果是溢出时,你的方法会做什么?
我的观点是,它并不总是像你想象的那么简单.
单元测试的目的不是为了确保你的代码在编写时有效(因为面对它,如果你编写了代码和单元测试,那么你要测试的就是你在考虑时所考虑的相同的角落情况正在编写代码),但要确保下一个bozo与您的代码做一些事情不会打破它.即使那个bozo是你.