”测试驱动开发”技术现在越来越受关注,它有助于我们开发出简洁可用、质量可靠的代码。与其说它是一种技术,还不如说是一种开发思想,一种不同于传统开发模式的思想。以前的开发环境对于“测试驱动开发”模式并没有良好的支持,而习惯于面向对象的开发人员来说,先写测试用例真的是够复杂的一件事,还不如“先开发后测试”来得高效。然而,在clojure这里,一切都不是问题,而这主要得益于midje这一测试框架(个人经验之谈)。本文主要讲解midje测试框架在clojure开发中的应用。
一、midje测试框架的搭建
midje测试框架依赖midje库和lein-midje插件,在project.clj中如下配置:
(defproject midje-test "0.1.0"
:description "midje-test"
:dependencies [[org.clojure/clojure "1.6.0"]]
:profiles {:dev {:resource-paths ["etc"]
<strong>:dependencies [[midje "1.6.3"]]
:plugins [[lein-midje "3.1.3"]]</strong>}}
:uberjar-exclusions [#"(?i)^META-INF/[^/]*\.SF$"])
源代码文件如下:
<span style="font-size:14px;">(ns midje-test.action)
(defn plus
"两数求和"
[num1 num2]
(+ num1 num2))</span>
测试代码文件如下:<span style="font-size:14px;">(ns hjd-3d-prop-server.action-test
(:require [midje.sweet :refer :all]
[midje-test.action :refer :all]))
(fact "测试两数求和"
(plus 1 2) => 3
(plus 1 2) => 4)</span>
在终端窗口中输入lein midje 命令,将启动一次测试,上述代码中
<span style="font-size:14px;">(plus 1 2) => 3 ;测试通过</span>
<pre name="code" class="java"><span style="font-size:14px;">(plus 1 2) => 4 ;测试不通过,终端窗口输出框中则会提示出错位置(测试说明<span style="font-family: Arial, Helvetica, sans-serif;">"测试两数求和”及对应文件的</span>代码行)。</span>
输入lein midje :autotest命令,则会启动自动测试,即你在源代码或测试代码中修改代码并保存后,midje框架会自动进行测试并显示测试结果,不需要再手动编译运行代码...
二、midje测试驱动开发
正是有lein midje :autotest命令,你就可以进行“测试驱动开发”了,具体步骤可概括为:
(1)在测试代码文件中编写测试用例:函数命名、输入参数、期待输出的结果
(2)在源文件代码中完成函数定义:返回错误结果
(3)运行lein midje :autotest命令:(当然代码会通不过测试)
(4)修改不可用代码->通过测试的可用代码->重构并确保能通过测试。
clojure鼓励开发人员尽量编写纯函数,因而我们可以根据对函数的需求明确函数的输入输出,从而很简单就编写出测试用例代码。
三、midje测试功能介绍
midje提供了强大的测试功能,包括类似java mock的功能,重复测试等等,这里就不一一介绍,请参见lein-midje库和midje库介绍。
四、总结
个人觉得,clojure开发的效率已然很高,这不仅源于语言自身的优雅、与java类库的无缝对接、开源社区中丰富的库,还有就是它可以在REPL中进行尝试性开发,这比java开发中“开发->运行->开发->运行”的模式效率要高得多。另外,由于开源软件和插件的支持,clojure已经拥有一套稳定而便捷的开发环境。目前,自己正在使用的一套开发环境是“Intellij IDEA + leingen + cursive" , Intellij IDEA不管是开发JAVA还是Clojure都效率颇高,甚至觉得比Eclipse好用不少;leiningen则是构建clojure工程利器,让开发人员能够专注于业务逻辑开发;cursive插件则为编辑和阅读clojure代码提供了便捷的服务.......
“测试驱动开发”不仅助于编写简洁可用和高质量的代码,有很高的灵活性和健壮性,能快速响应变化,加速开发过程,还可以促使我们尽量编写纯函数(有明确的输入输出,无副作用),使每个函数都足够简洁、关注于某个功能,从而提高工程代码的整体质量。