《Junit单元测试管理.ppt》由会员分享,可在线阅读,更多相关《Junit单元测试管理.ppt(25页珍藏版)》请在三一文库上搜索。
1、单元测试管理要求,2014-05-14,单元测试的好处 可以提高代码质量; 有助于设计简单清晰而易用的接口; 模块切分的足够小但是模块间保持极低的耦合度; 测试代码是“活”的软件文档,它硬性规定了实现代码必须满足的需求,达不到就报错。 降低重构难度,可肆无忌惮的重构; 减少维护成本; 很容易构建集成测试,及自动测试。 成熟的开源框架或工具都有良好的单元测试代码,是很好的学习工具。,单元测试的意义,基本思想: 在开发功能代码之前,先编写测试代码。 在明确要开发某个功能后,首先想如何对这个功能进行测试,并完成测试代码的编写,然后编写相关的代码满足这些测试用例。再循环进行添加其他功能,直到完全部功能
2、的开发。 基本过程: 明确当前要完成的功能; 针对此功能的测试用例编写; 测试代码编译不通过; 编写对应的功能代码; 测试通过; 对代码进行重构,并保证测试通过; 循环完成所有功能的开发。,单元测试过程,Junit测试流程,4.0以上版本可以用注释(test)的方式来进行标注,Juint在eclipse的使用,JUnit的使用,Assert 断言 JUnit为我们提供了一些辅助函数,它们用来帮助我们确定被测试的方法是否按照预期的效果正常工作,通常,把这些辅助函数称为断言。 常用断言 assertEquals(a, b) assertFalse(a) assertTrue(a) assertNo
3、tNull(a) assertNull(a) fail(String message) JUnit 4 : /value : 接下来想要测试的变量值;matcher statement : 使用 Hamcrest 匹 配符来表达的对前面变量所期望的值的声明,如果 value 值与 matcher statement 所表达的期望值相符,则测试成功,否则测试失败。 assertThat( value, matcher statement),JUnit的使用,/ is匹配符表明如果前面待测的object等于后面给出的object,则测试通过 assertThat( testedObj, is( o
4、bject) ); / containsString匹配符表明如果测试的字符串包含指定的子字符串则测试通过 assertThat( testedString, containsString( “developerWorks“ ) ); / greaterThan匹配符表明如果所测试的数值testedNumber大于16.0则测试通过 assertThat( testedNumber, greaterThan(16.0) ); / closeTo匹配符表明如果所测试的浮点型数testedDouble在20.00.5范围之内则测试通过 assertThat( testedDouble, close
5、To( 20.0, 0.5 ) ); /hasItem匹配符表明被测的迭代对象含有元素element项则测试通过 assertThat(iterableObject, hasItem (element);,TestCase生命周期,单元测试应用,对我们比较有用的一些建议 用并行树的方式存放测试代码; 面向测试的设计 要如何对代码进行测试呢? 以前没有写过单元测试的代码怎么办? 对于后面新写的代码符合写单元测试的条件,就应该编写单元测试; 老代码如果需要重构,则可以优先考虑添加测试代码; 用单元测试来防止已捕捉的bug再次发生,也为借用maven等工具能进行持续的构建与测试。,Junit测试实践
6、,组测试TestSuites,组测试TestSuites; 异常测试; Mock在单元测试中的应用; Spring对单元测试的支持。,实践-组测试TestSuites,public class AllTests public static void main(String args) junit.textui.TestRunner.run(AllTests.suite(); public static Test suite() TestSuite suite = new TestSuite(“Test for junitdemo“); suite.addTestSuite(StringTest
7、.class); suite.addTestSuite(CalucatorTest.class); return suite; ,实践-Exception测试,实践-Mock Objects,允许你测试依赖于其它对象的方法,但那个对象非常难实例化或是太慢如资源类的等。 例1 要测试Servlet的doGet()请求:HttpRequest,HttpResponse可以使用Mock; 例2 要测试Service层的逻辑,但dao层要依赖数据库或是dao层只提供一个接口没有实现类;,实践-Mock:转帐实例,实践-Mock:转帐实例,public void testTransferOk() fin
8、al Account senderAccount = new Account(“1“, 200); final Account beneficiaryAccount = new Account(“2“, 100); Mockery context = new Mockery(); /使用MockAccountManager final AccountManager mockAccountManager = context.mock(AccountManager.class); context.checking(new Expectations() one(mockAccountManager)
9、.findAccountForUser(“1“); will(returnValue(senderAccount); one(mockAccountManager).findAccountForUser(“2“); will(returnValue(beneficiaryAccount); one(mockAccountManager).updateAccount(senderAccount); one(mockAccountManager).updateAccount(beneficiaryAccount); ); AccountService accountService = new Ac
10、countService(); accountService.setAccountManager(mockAccountManager); /转帐操作 accountService.transfer(“1“, “2“, 50); /验证 assertEquals(150, senderAccount.getBalance(); assertEquals(150, beneficiaryAccount.getBalance(); ,实践-Sping单元测试,Web mock Jndi mock 数据库测试,实践-Sping:web,MockHttpServletRequest,MockHttpS
11、ervletResponse,MockHttpSession: public void final testGettingToDetails throws Exception MyController myController = new MyController(); myController.setDetailsView( detailsViewName ); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServle
12、tResponse(); request.setMethod(“POST“); request.addParameter(“viewDetails“, “true“); ModelAndView modelAndView = myController.handleRequest(request, response); assertEquals(“Incorrect view name“, detailsViewName,modelAndView.getViewName(); ,实践-Sping:jndi mock,private ClassPathXmlApplicationContext c
13、ontext; public void testJndi( ) throws Exception context=new ClassPathXmlApplicationContext(springFiles); SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder(); DataSource ds = (DataSource) context.getBean(“dataSource“); builder.bind(“jndi:jdbc/DataSource“, d
14、s); / 现在你的数据源就是 “jndi:jdbc/DataSource“了 ,实践-Sping:数据库测试,public class MyTransactualControllerTest extends AbstractTransactionalSpringContextTests protected String getConfigLocations() return new String “classpath:/test/spring-context.xml“; public void testCorrectBehavior() throws Exception /运行该事务性方法
15、myTransactualController.submitPayment( new Payment( 100 ) ); assertTrue( myTransactualController.isValid() ); Junit4的写法: RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(locations = “classpath:app-config.xml“, “classpath:mvc-config.xml“) Transactional public class AccountServiceTest1 Test
16、 public void testGetAcccountById() Account acct = Account.getAccount(1, “user01“, 18, “M“); service.insertIfNotExist(acct); Account acct2 = service.getAccountById(1); assertEquals(acct,acct2); ,Junit4的新特性,兼容以往版本 不用强制继承TestCase类 使用注解(Annotation)来标注测试 对异常(exception)测试改进,public class Junit4Test Before
17、public void init() throws Exception System.out.println(“init()“); Before public void setUp() throws Exception System.out.println(“setUp()”); /两个Before After public void destroy() throws Exception System.out.println(“destroy()“); /增加Test表示为测试方法 Test public void replace() String result = “abc“.replace
18、(a, b); assertEquals(“bbc“,result); Test(expected=ArithmeticException.class) public void divide() int num = 9/0; /异常测试 ,开发规范,需要单元测试的代码 1、逻辑复杂的功能; 2、容易出错的代码; 3、不易理解的代码,即可能过段时间后自己也不易理解的代码,而单元测试代码有助于理解代码的功能和需求; 4、后期需求变更可能性相对比较大的,这样后期需求更变修改代码之后就不用太担心写的代码对不对以及是否破坏既存代码逻辑了; 5、项目团队根据行业惯例判断,需要进行单元测试的代码。,管理要求
19、: 1、项目经理在安排开发计划时,对需要做单元测试的功能做出明确要求,在要求必须开展单元测试的同时预留足够的单元测试时间; 2、开发人员在开发过程中,如果发现功能需要做单元测试时,应积极主动的开展单元测试工作,并告知项目经理。 监 督: 1、项目经理有责任监督项目组成员的单元工作是否按要求开展; 2、技术经理有责任监督项目组是否有开展适当的单元测试工作。,开发规范,考 评: 1、单元测试工作将与季度考评中的以下考评内容相关联: a、质量:按照公司或部门工作规范开展工作如:管理规范、技术规范(2分); b、质量:工作成果满足相应的工作质量要求如:需求、设计、代码(3分); c、质量:系统提交前有开展单元测试关键功能、集成测试、系统测试以及AB角测试(1分); 2、项目经理根据单元测试监督结果对项目组成员进行考评; 3、技术经理监督各项目组的单元测试工作,主要核查项目组是否正确开展单元测试工作,并提供事实依据给部门负责人对项目经理进行考评。,开发规范,结束,Q&A,
链接地址:https://www.31doc.com/p-3482027.html