`
unsid
  • 浏览: 8396 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

关于单元测试,还想发点牢骚

阅读更多
目前项目一直没有单元测试,所以大家一直在呼唤着口号,要把单元测试用起来,测试能不能驱动开发不好说(我觉得这个很难),至少测试能帮助减少一些问题的产生吧,在刚开始使用单元测试的时候,不必在意测试是在代码之前写还是之后写,能用起来并达到“测试不是开发的累赘而是帮助开发的工具”状态就是现阶段的任务。

下面,针对单元测试junit以及我微薄的理解,阐述一下我的牢骚所在吧
首先我认为,传统过程的单元测试是典型的白盒测试,一段代码产生可能在任何地方产生错误,这种错误有可能是一个异常中断,一个错误的返回值,存储数据库的时候少存一条记录,发送给远程客户端的信息不完整等等各种各样,而junit只能以黑盒方式,即返回值捕获可能出现的错误,因为单元测试错误出现的多样性,几乎不可能抽象出一种统一的方式来捕捉所有类型的错误。如果只有junit,那么能做的事情很少,好在我们有JMOCK,ORMUNIT,DBUNIT,XMLUNIT....等等工具来帮助测试,在经典的开发环境下(就像论坛里大多数人所处环境一样),junit配合那些工具能帮助程序将很多问题发现在萌芽里。
我仔细的看了POJO IN ACTION里面关于单元测试使用的例子
一个业务类的测试大概是这个形式:
Class Book{   
    BookDao dao ;   
    public Book(BookDao dao){   
       this.dao = dao;   
    }   
  
    public doSomething(){   
       ......   
    }   
}   
//想对这个book类的doSomething()作测试大致是这个样子   
Class usertest extends  MockObjectTestCase{   
   private Mock daoMock;   
   private Book;   
   public viod setUp(){   
       daoMock = new Mock(BookDao.class);   
       BookDao = (BookDao)daoMock.proxy();   
       Book = new Book(BookDao);   
   }   
   public void testDoSomething(){   
       daoMock.expects(once())   
              .method("add")   
              .with(eq(1))   
              .will(returnValue(true));   
       Book.doSomething();   
   }   

    Class Book{
        BookDao dao ;
        public Book(BookDao dao){
           this.dao = dao;
        }

        public doSomething(){
           ......
        }
    }
//那么想对这个book类的doSomething()作测试大致是这个样子
    Class usertest extends  MockObjectTestCase{
       private Mock daoMock;
       private Book;
       public viod setUp(){
           daoMock = new Mock(BookDao.class);
           BookDao = (BookDao)daoMock.proxy();
           Book = new Book(BookDao);
       }
       public void testDoSomething(){
           daoMock.expects(once())
                  .method("add")
                  .with(eq(1))
                  .will(returnValue(true));
           Book.doSomething();
       }
   }

问题就出在于并非项目中每个人都这样写book,而有人也许会这样写
Class Book{   
    public doSomething(){   
       BookDao dao = new BookDao();   
    }   
}  

    Class Book{
        public doSomething(){
           BookDao dao = new BookDao();
        }
    }


这样,BookDao非构造子注入,没办法用代理对象替换了,也许这样写的业务类就是不可测试的。。。
我在这里并不想和大家讨论这样写代码的开发人员素质是否高的问题,我想发的牢骚在于,测试本身和开发就是两种不同的思路,而单元测试并非轻易而使,他需要开发业务的人员去分心,除了沉陷于繁冗复杂的业务中以外,还要考虑如何写代码才能让代码可测试化。。这似乎有点本末倒置了。想实现单元测试,看来首先要知道如何写可测试的业务代码之后才考虑测试类怎么写。

这些看起来大家并不觉得有什么的,按照传统的SSH惯用方法业务类,通过ioc工厂让组件脱离于框架限制而成为“可本地化”的pojo类,则天然地也成为了可测试类。
但是对于一个不能用开源框架,只许用“用来向客户兜售”的公司内部框架开发,而且很多时候框架限制只能把类写成
   public doSomething(){
     BookDao dao = new BookDao();
   }

形式的时候,单元测试就显得不那么简单了。
1
0
分享到:
评论
6 楼 unsid 2009-01-23  
regular 写道

实际上说白了,既然你doSomething函数写成了这个样子,想把其中一块挖出去,用其它对象替代感觉是不太可能。而且……也没必要吧。 如果一定要用MOCK代替BookDAO,除非新建一个package,然后把mock放在那里。然后引用的包改成新建的包。 这是一个就不打算让你测的例子。因为如果想给别人测的话,写成这样就行了:


Java代码

public doSomething(){      
  BookDao dao = getBookDao();      
}   
  
protected BookDao getBookDao() {   
  return new BookDao();   
}  public doSomething(){  
  BookDao dao = getBookDao();  
}

protected BookDao getBookDao() {
  return new BookDao();
}
然后要测试的话,用一个子类重载一下getBookDao函数即可。


那其实也就等于说,要想在没有单元测试的地方,慢慢起用单元测试,首先要给开发人员制定规范,所有人严格按规范写,知道怎么能写,怎么不能写,通常用惯了SHH的人习惯性的都写成那种可测试的风格,因为SHH的惯用写法,不用专门说,对于应自己公司开发的框架就不好说了..
5 楼 regular 2009-01-23  
实际上说白了,既然你doSomething函数写成了这个样子,想把其中一块挖出去,用其它对象替代感觉是不太可能。而且……也没必要吧。

如果一定要用MOCK代替BookDAO,除非新建一个package,然后把mock放在那里。然后引用的包改成新建的包。

这是一个不打算让你测的例子。因为如果想给别人测的话,写成这样就行了:
public doSomething(){   
  BookDao dao = getBookDao();   
}

protected BookDao getBookDao() {
  return new BookDao();
}

然后要测试的话,用一个子类重载一下getBookDao函数即可。
4 楼 regular 2009-01-23  
TestNG。去看看。
3 楼 lzy.je 2009-01-18  
unsid 写道

lzy.je 写道
单元测试的粒度控制是重点,尤其是在引入这项任务的前期。

呵呵,这个您有什么高见,我认为写领域模型有助于细化单元测试的粒度,粒度细了,覆盖率就高了,如果一个业务写成一个事务脚本,虽然业务好实现,单元测试则起不到什么实质作用了.


我说的粒度两个层次,技术和非技术。

单元测试用例的多少确实和覆盖度有关系,不过反过来就不一定了,不能说用例少覆盖度就上不去,对吧。关于实现,我觉得stub、mock肯定少不了,否则高阶用例肯定没法搞定。
另外,这项工作涉及到工作量的问题,粒度细了覆盖率上去了,可要知道工作量自然也是增加不少了。这就是项目管理方面的问题。

你觉得呢?
2 楼 unsid 2009-01-18  
lzy.je 写道

单元测试的粒度控制是重点,尤其是在引入这项任务的前期。

呵呵,这个您有什么高见,我认为写领域模型有助于细化单元测试的粒度,粒度细了,覆盖率就高了,如果一个业务写成一个事务脚本,虽然业务好实现,单元测试则起不到什么实质作用了.
1 楼 lzy.je 2009-01-18  
单元测试的粒度控制是重点,尤其是在引入这项任务的前期。

相关推荐

    个人无聊发一发牢骚,别人不可用

    个人无聊发一发牢骚,别人不可用

    janken:JSF发牢骚

    总结来说,"janken:JSF发牢骚"项目是一个全面展示JSF功能的实例,涵盖了从基本的UI组件使用到高级的业务逻辑处理和用户体验优化。对于想要深入了解和掌握JSF的开发者,这是一个非常有价值的参考资料。通过分析和重构...

    发牢骚

    【发牢骚】:在IT行业中,"发牢骚"可能是指开发者在遇到技术问题或对编程语言特性不满时表达的抱怨。在这个场景下,我们聚焦于与TypeScript相关的牢骚,这是一种静态类型的JavaScript超集,旨在提高代码的可维护性...

    初中语文文摘职场牢骚带来的变革

    在现代职场中,变革往往是由微小的事件引发的,这些事件可能是员工的不满,也就是所谓的“牢骚”。索尼公司的变革,正是从一个普通的牢骚开始,最终引领了一场管理上的革新。索尼的案例不仅对职场人士有深远的启示,...

    三年级语文上册 第七单元复习题(近反义词、多音字)(无答案) 人教新课标版 试题.doc

    这篇文档是针对小学三年级语文第七单元的一份复习测试题,主要涉及近义词、反义词和多音字的学习。这些知识点对于小学生来说是基础且重要的,有助于他们提升词汇理解和语言运用能力。 1. **近义词**: - 固然:...

    团队精神测试大集合(doc34页).doc

    团队精神测试还涉及了合作对个人能力施展的影响,个人的能力通常在不同的阶段和环境中得到展现。不合作的后果包括缺乏成就感、怕担责任、爱发牢骚,并可能导致对团队和个人承诺的减少,进一步发展为从业状态的消极和...

    搜趣唠叨开源程序下载

    <br>友情提醒:如你在下载前想测试体验该程序的话,希望你注册后能认认真真的唠叨几句,而不是发些垃圾信息,如:测试。。。或者随便打一段字母或数字,如GHHJSAFQ#@QR-F2345367之类。不想因为搜趣唠叨开源供...

    STC的测试代码+红外学习遥控器

    没办法要用stc的,居然还有块最老的型号,就凑合着先写了些测试代码,最后选型了60s2做红外学习遥控,其实不需要选这个,画原理图的人图方便随便画了一个,失败的一个项目,个人上传只为留个脚印,也供大家参考 ************...

    广西壮族自治区贵港市贵城四中2020学年八年级英语下册 周测试试题(2)(无答案) 外研版.doc

    - 抱怨,发牢骚(complain) - 包括,包含(include) - 推动,督促(push) - 他(她,它)们自己(themselves) - 成年人(adult) - 自由(freedom) 2. **语法**: - 动词时态:如题目中的"The young ...

    广西壮族自治区贵港市贵城八年级英语下册 周测试试题(2)(无答案) 外研版 试题.doc

    把…除外"对应"except","心烦的,沮丧的"对应"upset","归还,送回"对应"return","到…为止"对应"by","合适,适应"对应"fit","压力"对应"stress","抱怨,发牢骚"对应"complain","包括,包含"对应"include",...

    2010年7月日语能力测试N1真题+听力原文+读解部分详细解答(免费下载)

    【日语能力测试N1真题详解】 日语能力测试N1是衡量非母语者日语水平的最高级别考试,对于希望在日本工作或学习的人来说至关重要。2010年7月的日语能力测试N1真题包含了听力、读解和词汇三个部分,旨在测试考生在...

    小学英语英语故事幽默故事YouShoulLearntoBemorepolite你应该学礼貌点

    例如,"whining about"表示“发牢骚”,"whining"是动词"whine"的进行时态,意为“抱怨”或“发牢骚”。在日常对话中,理解这些表达可以帮助我们更准确地表达情绪和态度。 5. 语言的多义性和情境理解。"whining...

    黑龙江省鸡西市鸡东县六年级语文下册第一单元第5课小溪流的歌学案无答案鲁教版五四制

    1. 学习和积累重要的汉字词汇,如“牢骚”、“沉淀”、“阻碍”等,这是基础语言学习的重要环节,有助于提高学生的识字能力。 2. 了解小溪流从形成到成长的过程,这一部分涉及地理和自然科学知识,可以帮助学生理解...

    个人集成平台

    唉,说到这里,我以前的公司就是用的这个框架做的应用程序,现在的公司虽然比以前的公司待遇好了,不过用不着做WPF了,也基本上不使用任何框架开发,郁闷啊,呵呵,发发牢骚。在我的“个人平台”里面,没有使用整个...

    mdb:角度js tmdb

    接下来,“发牢骚”(npm run)通常用于执行在项目`package.json`文件中定义的脚本,比如编译、测试或者构建任务。然后,“测试”说明了项目包含测试代码,确保代码的质量和功能的正确性。最后,“将CHROME_BIN设置...

    2018大学生职业发展与就业指导期末测试答案(17级) (2).docx

    这份期末测试的答案涵盖了多个核心知识点,涉及个人成长、职业选择、兴趣理论、职业技能、生涯规划等多个方面。 1. **专业成长与目标系统**:完成大学专业的体系化建构,需要按照专业培养目标进行系统成长,不仅仅...

    lv-dev:Letsventure测试的存储库

    LetsVenture测试 展示完整消息系统的angular-fullstack应用程序的仓库。 要运行此应用程序: 将仓库克隆并复制到克隆目录中 npm install && Bower安装 发牢骚

    2018大学生职业发展及就业指导期末测试答案17级.docx

    【知识点详解】 1. 职业发展与就业指导的核心在于按照专业培养目标系统成长,这意味着大学生应关注自身的全面发展,而不仅仅是记忆知识点或追求高分(答案D)。 2. 对于程序员而言,S型(根据MBTI性格类型,代表...

    springBoot tomcat6实现外部部署源码+war包

    springboot 实现外部tomcat6的部署,springboot+tomcat6 实现jsp技术,哥是个程序员,最近有点倒霉,很多话没地方去说,在这里发发牢骚:想赚点钱养家真难,炒股真危险,赚钱不够养家,买哪个股,哪个股大跌,不带...

    大学生职业发展和就业指导期末测试答案解析(17级).docx

    【大学生职业发展与就业指导知识点解析】 1. **专业体系化建构**:完成大学专业的体系化建构不仅仅是记忆知识点或追求高分,更重要的是按照专业培养目标进行系统性成长,这有助于形成扎实的专业基础和实际应用能力...

Global site tag (gtag.js) - Google Analytics