• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

软件测试中的一种新单元测试的方法

发布: 2009-11-03 15:53 | 作者: 网络转载 | 来源: 领测软件测试网 | 查看: 52次 | 进入软件测试论坛讨论

领测软件测试网

软件测试中的一种新单元测试的方法

一种新的单元测试的方法意味着什么?难道说Junit或者TestNG还不够好?Junit(这里我提及到它因为它简单,但是在我的讨论中,TestNG 也一样简单 from here on I’ll nominate it only for briefness,but TestNG is the same for my discussion)把测试类作为重点,并且所有的测试都是从那里开始。这意味着事实上,被测试类被认为仅仅存在于测试代码中,程序员只能通过它们使用的名字惯例来找到这些被测试类。

在旧版本的Junit中,你设计的测试类,需要强制继承Junit框架中的类,并且将调用的方法需要用"test"开头。因此按这个惯例来命名测试类和测试方法,并把他们与被测试的类和方法“连接”起来。我想你会同意,TestNG和Junit4给了我们更多的自由,去掉这些要求。不管怎样,被测试的类和方法和我们的测试类仍然是这样逻辑的联系在一起,并且很多测试类仍然遵循那些旧的惯例。

但是有很多更好的方式来命名类和方法!我来介绍BDD(Behaviour Driven Development),请注意BDD不是这篇文章的重点,但是它使我这篇文章更加完美。因此,让我们先用少许文字了解BDD吧。

BDD不仅是一个新的写测试的方法,也是一个按约定的新的设计形式

引用behaviour-driven.org来开始我的介绍:

BehaviourDrivenDevelopment grew out of a thought experiment based on NeuroLinguisticProgramming techniques. The idea is that the words you use influence the way you think about something

BDD产生自一个基于神经语言规划学技术的实验的想法。这个想法是你用的语言会影响你考虑问题的方式。

这个想法是需要程序员关注用来描述一个测试类或者方法的词语,因为所选的词语将影响到他们对这个问题的关注点。实际上,采用BDD方法写测试类时,相比这些被测试的类/方法本身,我们将更加关注这些被测试类/方法的行为。当然,这也将改变很多我们写测试代码的方式,比如,我们将对一个方法测试多次来验证每个行为是否正确。

OK, what if I don’t believe on Neuro Linguistic Programming(神经语言规划学)?是否我还不相信神经语言规划学。好的,从一个纯粹的开发者角度来看,我们根据我们的类和方法的行为作为约定来命名测试,因此,这个测试结果将是绝对清晰的(比如,

“shouldAcceptNullValue fails”就是一个清楚的表达,并不需要复杂的报告)。让我们提供一个简单的例子:

Java代码

  1. @Test( expected = IllegalArgumentException.class )
  2.
public void shouldNotPermitMethodNull() throws Exception {
  3. [..]
  4. }
  5. @Test( expected = IllegalArgumentException.
class )
  6.
public void shouldNotPermitEndPointNull() throws Exception {
  7. }
  8. @Test
  9.
public void shouldInitWebParams() throws Exception {
  10. }
  11. @Test
  12.
public void getHoldersResultShouldReturnHolderForRightParameters() throws Exception {
  13. }
  14. @Test
  15.
public void getHoldersResultShouldIgnoreUnknowntParameters() throws Exception {
  16. }
  17. @Test
  18.
public void getHoldersResultShouldIgnoreINParameters() throws Exception {
  19. }
  20. @Test
  21.
public void shouldRuninvokeForOneWayMethod() throws Exception {
  22. }
  23. @Test
  24.
public void shouldRuninvokeForMethods() throws Exception {
  25. }
  26. @Test
  27.
public void shouldRuninvokeForMethodsApplyingMapping() throws Exception {
  28. }

你需要一个简单的关于如何使用BDD成功应用到java上的介绍吗(最初的主意来自Ruby’s RSpec)?可以先看看excellent post.

那么BDD就够了吗?

答案当然是NO。BDD是很强大,你可以试一下,但是如果你真正的用于实践,你就会发现这些测试类和被测试类很快就会失去其联系。在BDD中,不仅仅测试方法不再是testXXX,那些测试类也可能不再是按约定取的名称。或者,你可能针对同一个被测试类/方法,会拥有多个测试的方法。例如之前的那个例子,当然不是很贴切,可能一个具体的测试类,比如来测试getHolder方法的行为的测试类更好一点。

你需要帮助吗?这是我的新的项目TestedBy

通过注释来标注被测试类和方法,来使其与测试类和方法联系在一起,怎么样?不是太坏,你说呢?

我的想法或多或少从这里开始,但是不仅限于一个注释。我很高兴这个主意,因此我决定开始一个新的开源项目来提供测试工具,用来把被测试类放到中心的位置。

继续看,我将展示给你如何通过注释和相关工具来改变你测试的方法。

TestedBy目标在于改变观察测试类和被测试类的角度。我们可以把被测试的类(项目中最重要的类)放在中心位置,并可从这些类连接到他们的测试类和方法。一个代码快照可能抵得上更多的解释:

Java代码

  1. public class TestedBySample {
  2.
  3.
/**
  4. *
@param args
  5. */

  6.
public static void main( String[] args ) {
  7. TestedBySample sample =
new TestedBySample();
  8. System.out.print(sample.add(1, 2));
  9.
  10. }
  11.
  12. @TestedBy( testClass = "it.javalinux.testedby.TestedBySampleTest", testMethod = "addShouldWork" )
  13.
public int add( int i,
  14.
int j ) {
  15.
return i + j;
  16. }
  17. @TestedByList( {@TestedBy( testClass = "it.javalinux.testedby.TestedBySampleTest", testMethod = "addShouldWork" ),
  18. @TestedBy( testClass = "it.javalinux.testedby.TestedBySampleTest", testMethod = "addShouldWork2" )} )
  19.
public int add2( int i,
  20.
int j ) {
  21.
return i + j;
  22. }
  23.
  24. }

很好吧,但是它确实改变了你单元测试的方法?我觉得是,怎么样,至少在两个方面。

1、通过接口和约束来设计Design by interface and contracts

软件设计中著名的词语说“Design by interface”,仍然在我耳边响起。因此你也当然可以“Test interface”。

很多正式的“Design by interface”意味着定义好你的接口,并且接着实现它们(可能大部分时间是由不同的人或者公司来实现)。总之,你能够影响到的只是如一个强类型语言,例如java能为你提供的那样:一个接口的实现必须遵循接口的签名,类型和参数变量保持一致。你不能控制到那些具体的行为。当然,这也是一个API设计上的一个很大的局限性,因为可能导致实现完全不可预期的行为。

这里我就引出Eiffell language 和他的 design by contract (DbC)方法,约定来引导继承过来的特征的重新定义。在java中有很多工具支持Dbc,但是我的想法是我们已经有一个很强大的方式来测试方法上的约束,并且使用更少的代码来清楚行为:Unit Tests单元测试。

使用TestedBy,测试在接口(或者父类)上声明,所有实现类都能运行这些测试,来验证这些实现类的行为,是符合父类类型上的行为和约束定义的。API设计者不仅提供接口,也提供一套验证该接口行为的测试类。因此每个实现者需要提供他们自己的实现,并且运行API设计者提供的测试,来保证实现类不仅是类型安全的,也是行为安全的。TestedBy传递给测试类一个被测试接口的实体类,并调用接口定义好的测试。

这是一个使用TestedBy的例子:我们已经添加了@TestedBy注释在API接口,并提供一个@BeforeTestedBy注释来提供一个接口的实例。TestedBy将在实现类APIImplOne和APIImplTwo上运行shouldAddTwoAndThree,测试在第一个类上成功而在第二个类上失败。

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/

TAG: 单元 软件测试

21/212>

关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网