2017-03-08 51 views
0

我有一个办法做很多事情,所以这意味着许多副作用被创建。例如,假设对REST API的单个调用返回一个包含许多字段的JSON对象。在这种情况下,如果我们想要检查每个单独的字段,我们是否应该有一个包含许多assertEquals的单一测试方法,或者每个字段验证是否应该包含一个包含一个assertEquals的单个测试方法。在这种情况下有多少测试用例?

同样,一个方法可以有许多其他副作用,例如,保存到数据库,发送电子邮件等。在这种情况下,我应该有一个单位测试方法每边影响?

此外,如果每个SUT方法有多个测试输入,那么这是否会影响决定创建多少测试方法?

此外,它可能与故事有关,故事说这个故事说这个,这个子功能属于这个故事,不应该属于同一个测试方法吗?因为如果需求发生变化,那么每一侧的所有测试方法都需要改变。那可以管理吗?

回答

0

在,如果我们要检查每一个人领域,我们应该有一个单一的测试方法,其中将包含许多的assertEquals还是应该每个含一个的assertEquals字段验证一个单一的测试方法这种情况。

担心在测试情况下断言的编号类似于担心多少行是在一个功能。这是复杂性的一阶近似,但它不是真正应该关注的。

你应该关心的是测试要保持多久,以及它的诊断有多好。当测试失败时,你能弄清楚为什么?这很大程度上取决于你的assertEquals有多大的数据结构。

json = call_rest(); 
want = { ...whatever you expect... }; 
assertEquals(json.from_json(), want); 

如果这只是告诉你他们不平等,那不是很有用。然后您必须手动进入并查看jsonwant。如果它抛弃了这两种数据结构,那也不是非常有用,你必须通过目光寻找差异。

但是,如果它提供了两个数据结构的有用差异,那很有用。例如,Perl的Test2将产生这样的诊断。

use Test2::Bundle::Extended; 

is { foo => 23, bar => 42, baz => 99 }, 
    { foo => 22, bar => 42, zip => 99 }; 

done_testing; 

# +-------+------------------+---------+------------------+ 
# | PATH | GOT    | OP  | CHECK   | 
# +-------+------------------+---------+------------------+ 
# | {foo} | 23    | eq  | 22    | 
# | {zip} | <DOES NOT EXIST> |   | 99    | 
# | {baz} | 99    | !exists | <DOES NOT EXIST> | 
# +-------+------------------+---------+------------------+ 

然后还有维修问题,这再次归结为如何好你的assertEquals是。一个assertEquals很容易阅读和维护。

json = call_rest(); 
want = { ...whatever you expect... }; 
assertEquals(json.from_json(), want); 

有很少的代码,want是什么预期非常明确。

虽然倍数很罗嗦。

​​

可能很难知道哪些断言失败,你必须按行号,或者告诉(如果您的测试套件支持的话)手动命名每个断言这是更多的工作,更多的维护还有一两件事让错误。

OTOH个人assertEquals允许更多的灵活性。例如,如果您只想检查某些字段,该怎么办?如果在一个范围内有可接受的值会怎么样?

# bar just has to contain a number 
assert(have['bar'].is_number); 

但是一些测试套件通过单个断言来支持这一点。

want = { 
    thiskey: 23, 
    thatkey: 42, 
    foo:  99, 
    bar:  is_number 
} 

assertEquals(json.from_json, want); 

is_number是一种特殊的对象,告诉断言这不是一个正常的质量检查,但只检查该值是一个数字。如果你的测试套件支持这种风格,它通常优于写出一大堆断言。声明式方法意味着更少的代码来编写,读取和维护。

答案是:这要看你的测试工具有多好!