The ruby way test
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
878
On Slideshare
878
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
5
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. The Ruby Way (Test) Meet a Test world [email_address]
  • 2. 什么是测试? 1. 测试是通过一系列手段检查边界,检查可能出现问题的的地方,对运行数度和并发性进行测试,查找代码的漏洞,向软件设计,开发者和用户展示软件系统的不稳定和不可交付性。 2. 广义的说,测试是通过种种手段收集问题,生成报告,向项目决策者提供决策依据,测试人员又称为质量保证人员,是软件开发的最后一道关卡。 3. 测试的目的 不是为了证明软件可以正确运行,与此相反,测试的目的是为了找到软件的漏洞,从而证明程序代码是否能交付。
  • 3. 测试的内容 1. 在测试中,按照测试的时间顺序和目的,分为: 单元测试 , 模块测试 , 集成测试 。 单元测试 :对被测代码每一个函数边界和功能检查。 模块测试 :当软件被按照模块划分开发时,在模块耦合之 前,对每一个模块进行的检查。 集成测试 :对于模块整合之后的测试或称为系统测试。
  • 4. Ruby 中 测试框架 1.Ruby 是一个非常注重测试的语言,提供了一套测试框架,以进行单元测试和集成测试,名称为 RUBY 单元测试框架: ( Ruby Unit Testing Framework) ,保存与 Ruby 的 Runt 目录,包括 TestSuite , TestCace , tests , 和 Assertions 4 个部分 .
  • 5. 测试框架 1. 通过加载一行代码 require ‘test/unit’. 就给 Ruby 脚本加上了编写测试用例的能力。 一个简单的’ Hello world’ 测试例程( TestCase ): #hello_test require ’test/unit’ class TC_HelloTest<Test::Unit::TestCase def test_hello puts “test_hello” assert true end end 测试的结果如下: Loaded suite testhello started test_hello
  • 6. Finished in 0.0 seconds. 1 tests,1assertions,0 failures, 0 errors 上面的输出结果: 1 tests,1assertions,0 failures, 0 errors 代表测试组合的测试已经成功执行,它有一个测试,一个断言,耗费了 0.0 秒, 0 failures, 0 errors 没有一个错误。下面是对代码的解释: 1.require ‘test/unit’ 在编写单元测试的时候,应该始终包含 require ‘test/unit’ ,它包含了可以编 写和运行单元测试的类和功能,提供对测试组合的操作。 2 . class TC_HelloTest<Test::Unit::TestCase 必须有一个 Test::Unit::TestCase 的 派生类 , TestCase 类是测试例程的宿主 3 . def test_hello 测试执行的函数,输出 “ test_hello” ,所有的测试方法必须遵循如下命名规范:名称必须以 test 开头,测试框架将不认为它是测试方法,也不会自动运行,他是一个普通 Ruby 方法。 4. assert true 断言是测试方法
  • 7.
    • 在 Ruby 的测试模块中有 4 个主要的角色,角色如下:
    • TestSuite:
    • TestCase:
    • tests:
    • assertions:
    • 他们之间的关系是 : TestSuite<<TestCase<<tests<<assertions.
    TestSuite TestCase test test he TestCase Test Assertion1
  • 8. 1.Test Suite( 测试组合 ) :一个测试组合是一大堆测试用例的集合,运行了一个测试组合以后,它将执行该测试组合中的每一个属于它的测试,例如,可以通过创建一个测试组合,来包含每一个测试单元,这有利于小组不断的进行进行编译和打包集成,有利于提高测试速度和测试的质量,上面的 testhello.rb 就是一个测试组合。 2.TestCase (测试例程): 测试例程是一个继承与 Test::Unit::TestCase 的类,包含了以 test 开头命名的测试方法,以及和内容相关的测试策略。 3. tests (测试)方法 :包含了断言和测试操作的方法,以 test 开头,表示某一特定的测试场景。 4.assertion( 断言 ) :用来判断一个对象(或表达式)是否是希望的结果。
  • 9. 测试流程 一个简单的测试框架: 在下面测试代码中, UserVerify 用于表示用户校验模块,测试一个用户密码是否符合客户制定的安全规则, UserVerify 中的 is_pass_format_ok? 方法将处理这个问题,如果用户的密码通过了测试规则,将返回 TRUE, 否则,将返回 FASLE 并且断言立即中止,不再执行。 测试代码: class UserVerity attr_accessor :username ,:password def initialize(username,password) @forbidwords =[‘123456’] @username =username @password =password end
  • 10. def is_pass-format_ok? return false if @password.nil? return false if @password.empty? return false if @password.size < 6 return false if @ forbidwords? (@ password ) return false if @password =~/[rnt]?/ return false if @password == @username true end end
  • 11. 使用测试框架示例: require ‘test/unit’ class TC_UserTest < Test::Unit::TestCase def test_hello assert true end def test_passwords assert UserVerity.new(“root”,”abc”).is_pass_format_ok? assert UserVerity.new(“root”,”123456”).is_pass_format_ok? assert UserVerity.new(“root”,”1234567890”).is_pass_format_ok? assert UserVerity.new(“root”,”password”).is_pass_format_ok? assert UserVerity.new(“root”,”user”).is_pass_format_ok? assert UserVerity.new(“root”,”root”).is_pass_format_ok? assert UserVerity.new(“root”,”nil”).is_pass_format_ok? assert UserVerity.new(“root”,”1”).is_pass_format_ok? assert UserVerity.new(“root”,”n”).is_pass_format_ok?
  • 12. 这段程序的输出结果如下所示: Loaded suite userpwd Started . F Finished in 0.016 seconds. …… . 测试用例错误的详细信息 注意 Started 下面的 . F (小圆点和 F ) . : 测试通过。 F :测试失败 。 E :发生错误。
  • 13. Test::Unit 支持的断言
    • assert(boolean,[message])
    • 如果为 false 或 nil ,则失败
    • assert_nil(obj,[message])
    • assert_not_nil(obj,[message])
    • 预期对象为 nil (或不为) nil
    • assert_equal(excepted,actual,[message])
    • assert_not_equal(excepted,actual,[message])
    • 使用 == 来判定 excepted 和 actual 是否相等
  • 14. NetBeans 中的测试
    • Rails 创建应用程序的时候就已经生成 Test 整个目录 :
  • 15.  
  • 16.
    • 模型的测试叫做 单元测试 ( unit test ) , 控制器的测试叫做 功能测试 ( functional test ) , 对横跨多个控制器的业务流程进行的测试被称为 集成测试 ( integration test ) .
    • 单元测试 :
  • 17. 测试专用数据库:
  • 18.
    • 使用 rake: db:test:prepare 任务,拥有了测试数据库和数据库架构。
    • (NetBeans 中如何使用已有讲解 PPT)
    • 测试夹具 Test Fixtures
    • 负责指定模型对象初始的内容,使测试的表在每个单元测试开始之前具有同样的内容,在 yaml 文件中创建测试数据,文件名必须与表名相匹配。
  • 19.
    • 在执行每个测试方法之前, fixtures() 方法会根据指定的模型名称自动的加载对应的夹具,将其载入数据库:
    • 加上 fixtures 指令意味在执行测试方法之前,表会首先清空,然后填上夹具中的记录。每个测试方法都会使用一张全新的表。
    • 使用模型类型提供的查找方法来读取数据,只要传入 yaml 夹具中定义的记录名称,例: Product.new( :id => products(:ruby_book).id), 该方法返回包含该条记录的数据的模型对象,其中包含在夹具中定义的数据。
  • 20.  
  • 21. 控制器的功能测试:
    • 功能的约定:
  • 22.  
  • 23.  
  • 24.  
  • 25.  
  • 26.
    • 功能测试的关键在于 setup() 方法,它为每个功能测试方法初始化三件东西。
    • @controller: 需要测试的控制器实例
    • @request 包含了一个请求的对象
    • 请求对象包含了所有输入的请求信息和数据: http 头信息 ,post 和 get 数据等,在测试环境下,我们会使用一个特别的请求对象,不依赖于真是的请求 (Mock).
    • @response 包含了一个应答对象
    • 每当处理来自浏览器的请求时, RAILS 都会准备一个应答对象,模板会将数据渲染到应答对象中,返回的状态码也会记录在应答对象中,应用程序完成请求处理后, RAILS 就会取出应答对象中信息,根据这些信息向浏览器发送应答。
  • 27.
    • 通过脚本创建 Controller
  • 28.  
  • 29. 修改后:
  • 30.  
  • 31. 动态夹具
    • 正如我们所料,除非有用户登陆,才能使用那些 action (前置过滤器),所以我们要模拟一个登陆用户,将用户 ID 放入 session 中, 用户的 ID 必须是合法的。创建 yaml 文件:
    • Yaml 文件中依然可以调用模型对象
    • 最后在测试类中加上 fixtures 声明。
  • 32. Mock :
  • 33.  
  • 34. 参考文章:
    • http://www.builder.com.cn/2007/0901/482329.shtml
    • http://www.51testing.com/?action_viewnews_itemid_70460.html
    • http://www.cnblogs.com/dahuzizyd/archive/2007/11/20/ruby_rails_dotnet_study_24.html
    • http://my4java.itpub.net/post/9983/55687
    • http://www.ruby-lang.org.cn/forums/viewthread.php?tid=2342
    • http://www.cnblogs.com/dahuzizyd/archive/2007/11/20/ruby_rails_dotnet_study_24.html
  • 35. To Be Continue……