Ruby单元测试框架
单元测试是的核心部分。XP是伟大的,单元测试已出现了很长一段时间,而且它是一个很好的思想。好的单元测试的关键部分不是写测试代码,而是要测试。两者有什么不同吗?当然,如果你只是写测试代码而不用它,那么你以后对代码的修改将不会得到保证。换句话说,如果你已经测试(当然你首先要写测试代码),然后经常运行它们,那么你慢慢地建立了一个好习惯,虽然你不能马上知道它的益处。进入单元测试,则Ruby内的用于单元测试的框架会帮助你设计,调试和评估你的代码,而你要做的就是写测试代码并运行它。用法:单元测试的隐含思想是让你写一个测试方法,该方法为你的代码写些断言,然后进行测试工作。大多数这些测试方法被打包到一个测试单元中,并可在开发者需要的任何时候运行。运行的结果被收集在测试结果中并通过一些UI显示给用户。让我们先看看Test::Unit提供了哪些必需的部分。断言:框架的中心思想是要将断言做为期望输出的语句,也就是,“我断言这个x应该等于y”。当断言被执行时,如果它返回是正确的,不会有事发生。换句话说,如果你的断言失败,则错误信息会反馈给你,以便你返回修改直到你的断言成功。对断言的详细解释,可参考Test::Unit::Assertions。测试方法与测试模具明显地,这些断言必须在上下文环境中被调用,而这个上下文环境知道它们,并可以用它们的pass/fail值来做些事情。同样,它也可以很方便地收集相关的测试,每个测试用一个方法表示,然后放在一个知道如何运行它们的类中。有三个原因,要将测试同它们要进行测试的代码分开存放。首先,它可使你的测试代码整洁并易于管理。其次,它允许分离测试代码,因为它们只对你有用,而对用户没用。第三,它允许你设置通用的测试模具来重复测试。 什么是测试模具?测试不存活在真空中;而是依赖于它们所要测试的代码。通常,测试集依赖于一组数据,也可称为模具。如果它们被打包在同一测试类中,它们或以共享这些数据的设置与解除,即setup与teardown方法。这可去除不必要的重复,并使模具可以容易地添加其它测试。Test::Unit::TestCase包装测试方法在容器内,并允许你很容易地为每个测试设置和解除相同测试模具。这都是通过覆写setup或teardown方法来做到,它们将在每个测试方法运行前及运行后被调用。TestCase也知道如何收集你在Test::Unit::TestResult中的断言结果,然后它将报告显示给你。想写一个测试,得依循下面步骤:l 确保Test::Unit在你的库路径上。 l 在测试脚本中请求‘test/unit’。 l 创建Test::Unit::TestCase类的子类。 l 为你的类添加以"test"开头的方法。 l 在你的方法内使用断言。 l 可按需要定义setup或/及teardown来设置你的测试模具。 l 现在你就可以运行你的测试了。 一个相对简单的测试看起来可能是这样(setup和teardown通常不用给出,它们可选的):require 'test/unit'class TC_MyTest < Test::Unit::TestCase# def setup# end# def teardown# enddef test_failassert(false, 'Assertion was false.')endend测试运行器现在,你有了测试类,但是你还需要一种方式来运行它,并观察在运行期间可能发生的任何失败。它就是Test::Unit::UI::Console::TestRunner(或是其它的,如Test::Unit::UI:GTK::TestRunner)。如果你在源文件请求了’test/unit’并运行了这个文件,则控制台测试运行器是自动被调用给你的。若是想使用其它运行器或手工管理运行器,可简单地调用它的run类方法并传递一个对象给它,这个对象应处理Test::Unit::TestSuite的suite消息。传递到你的TestCase类(这个类有一个suite方法)内也这么简单。看起来一个实现应该是样的: require 'test/unit/ui/console/testrunner'Test::Unit::UI::Console:: n(TC_MyTest)测试单元工程内的测试单元会越来越多,它终会变得在运行时缓慢。同时它也会让你得到潜在的测试