美文网首页
测试驱动开发(TDD)

测试驱动开发(TDD)

作者: JayZJU | 来源:发表于2017-03-11 13:49 被阅读0次

    测试驱动开发(Test-driven development)在维基百科上的定义是一种软件开发过程中的应用方法,由极限编程中倡导,以其倡导先写测试程序,然后编码实现其功能得名。测试驱动开发始于20世纪90年代。测试驱动开发的目的是取得快速反馈并使用“illustrate the main line”方法来构建程序。简单来说,就是从用户的角度先编写测试用例,再实现功能代码,再进行重构和代码测试。

    现在就以liteStruts为例,简要说明TDD开发的过程。liteStruts所要实现的功能是读取struts.xml,执行Action,例如用户需要登录(login),发出请求后,web应用(Struts类对象)

    1. 首先解析struts.xml配置文件,其中有一个execute(String actionName,Map parameters)方法;
    2. 然后根据actionName找到对应的类class,反射实例化Action对象,调用setter方法设置该对象参数parameters
    3. 第三步反射执行Action对象的execute获取返回值;第四步通过Action对象getter返回参数,
    4. 最后返回View视图对象。

    现在就以第一步——解析struts.xml为例,进行测试驱动开发。因为struts.xml文件如下

    <?xml version="1.0" encoding="UTF-8"?>
    <struts>
        <action name="login" class="com.coderising.litestruts.LoginAction">
            <result name="success">/jsp/homepage.jsp</result>
            <result name="fail">/jsp/showLogin.jsp</result>
        </action>
        <action name="logout" class="com.coderising.litestruts.LogoutAction">
            <result name="success">/jsp/welcome.jsp</result>
            <result name="error">/jsp/error.jsp</result>
        </action>
    </struts>
    

    我们需要根据execute(String actionName,Map parameters)方法的actionName,来解析xml文件,获取对应的类名。因此,先编写测试类

    package com.coderising.litestruts;
    
    import org.junit.After;
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    
    public class ConfigurationTest {
        Configuration cfg = new Configuration("struts.xml");
    
        @Test
        public void testGetClassName() {
            
            String clzName = cfg.getClassName("login");
            Assert.assertEquals("com.coderising.litestruts.LoginAction", clzName);
            
            
            clzName = cfg.getClassName("logout");
            Assert.assertEquals("com.coderising.litestruts.LogoutAction", clzName);
        }
    }
    

    其中,Configure对应于xml解析结果。ConfigurationTest对应测试类。从测试类中可以看出,我们铜鼓哦调用Configure的对象,调用其getClassName方法,传入login参数,来获取我们希望的类名,最后进行断言,判断类名是否正确,这就是简单的测试用例开发。
    然后,我们开始开发解析结果Struts.xml类的开发(所需功能)。

    package com.coderising.litestruts;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.jdom2.Document;
    import org.jdom2.Element;
    import org.jdom2.JDOMException;
    import org.jdom2.input.SAXBuilder;
    
    public class Configuration {
        Map<String,ActionConfig> actions = new HashMap<>();
        public Configuration(String fileName) {     
            String packageName = this.getClass().getPackage().getName();
            packageName = packageName.replace('.', '/');
            InputStream is = this.getClass().getResourceAsStream("/" + packageName + "/" + fileName);
            parseXML(is);
            try {
                is.close();
            } catch (IOException e) {           
                throw new ConfigurationException(e);
            }
        }
        
        private void parseXML(InputStream is){
             SAXBuilder builder = new SAXBuilder();
             try {
                Document doc = builder.build(is);
                Element root = doc.getRootElement();
                for(Element actionElement : root.getChildren("action")){
                    String actionName = actionElement.getAttributeValue("name");
                    String clzName = actionElement.getAttributeValue("class");
                    ActionConfig ac = new ActionConfig(actionName, clzName);
                    for(Element resultElement : actionElement.getChildren("result")){
                        String resultName = resultElement.getAttributeValue("name");
                        String viewName = resultElement.getText().trim();
                        ac.addViewResult(resultName, viewName);
                    }
                    this.actions.put(actionName, ac);
                }
            } catch (JDOMException e) {
                throw new ConfigurationException(e);
            } catch (IOException e) {
                throw new ConfigurationException(e);
            }
        }
    
        public String getClassName(String action) {
            ActionConfig ac = this.actions.get(action);
            if(ac == null){
                return null;
            }
            return ac.getClassName();
        }
    }
    

    这里,使用jDom2来解析我们的struts.xml文件,用一个map结合actions储存我们的结果。这样编写实现功能之后,我们就可以开始测试我们的功能代码是否正确。于是,回到ConfigurationTest类,我们进行JUnit单元测试,测试通过。如果,发现有可以重构的代码,我们可以进行重构简化。
    在完成该作业的过程中,可以按照这种TDD的思路进行功能开发。这样做,有好处:

    1. 可以有效的避免过度设计带来的浪费。
    2. 开发者在开发中拥有更全面的视角。

    相关文章

      网友评论

          本文标题:测试驱动开发(TDD)

          本文链接:https://www.haomeiwen.com/subject/dnbagttx.html