• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    跨越邊界: 在集成框架中進行測試,第 1 部分

    發布: 2007-5-24 22:03 | 作者: Bruce Tate | 來源: IBM | 查看: 43次 | 進入軟件測試論壇討論

    領測軟件測試網 Java ™ 社區在推進自動單元測試方面已經做了一項激動人心的工作。越來越多的開放源碼框架支持在構建項目的同時構建自動測試套件。Spring framework、JUnit、TestNG 和其他幾個框架的一些或全部靈感都來自自動測試的思想。盡管如此,一些非 Java 語言和框架具有更多的測試動機、更合適的測試工具和更統一的測試視角。通過觀察其他框架的測試方式,可以改進 Java 語言中的測試方式,甚至使用更合適的語言來測試 Java 代碼。這篇文章是關于在 Ruby on Rails 上進行測試的兩篇文章中的第一篇,將介紹 Rails 單元測試的方式。

    捕獲 bug

    我還記得當我第一次得到自動測試的 bug 時的情況。在一次大會上,當我做完叫做 Bitter Java 的演講之后,Mike Clark(Java 社區的自動測試大師,性能調整工具 JUnitPerf 的作者(請參閱 參考資料),現在是 Ruby on Rails 專家)走近我。Mike 告訴我有一種方法可以通過自動測試改進我的演講。在那次大會的剩余時間里,我跟著他四處走,看到了我能看到的盡可能多的他的測試會議。我開始使用他推薦的技術,并對把紅條(代表測試失。┳兂删G條(代表測試通過)上了癮。自動測試改變了我思考軟件開發的方式。

    關于本系列

    跨越邊界 系列中,作者 Bruce Tate 提出了這樣一個觀點:如今的 Java 程序員可以通過學習其他方法和語言得到很好的其他思路。自從 Java 明顯成為所有開發項目的最佳選擇以來編程前景已經改變。其他的框架正影響構建 Java 框架的方式,從其他語言學到的概念可以影響您的 Java 編程。您編寫的 Python(或 Ruby、Smalltalk ... )代碼可以改變您處理 Java 編碼的方式。

    本系列為您介紹與 Java 開發根本不同,但也可以直接應用于 Java 開發的編程概念和技術。在一些例子中,需要對技術進行集成以利用它。在另外一些例子中,您將能夠直接應用這些概念。單獨的工具不及其他語言和框架能夠影響 Java 社區中的開發人員、框架甚至基本方法的思想那么重要。

    Java 社區絕對有自動測試的 bug。坦白地說,我們別無選擇。競爭壓力迫使許多公司編寫越來越多的代碼,而測試人員越來越少,同時每個開發人員的又必須有更高的生產率。如果不進行自動測試,得到測試的內容就會更少,面對現代應用程序不斷增長的復雜性,較少的測試不是一個可行的選擇方案。

    在過去十年中,我們已經看到了對測試工具和技術的研究。JUnit 和 TestNG 都是支持自動單元測試的優秀工具,而且由日常的開發人員所驅動。Selenium 是改進集成和功能測試的工具。一套稱作敏捷技術 的新開發過程告訴人們要更加重視自動測試,不要太多地依賴正式的設計工具,將它們作為提高質量的惟一工具。Java 社區已經走了很長的路。 (請參閱 參考資料,獲得這里討論的工具與技術的附加信息。)

    其他編程社區也有 bug 工具, 其中一些社區使用的自動測試要比 Java 開發人員還有多,他們使用自動測試經驗有完全不同的原因:

    • Smalltalk 程序員使用自動測試已經幾乎有 30 年的時間了,所以通過動態類型化語言使用的一些技術更加先進。

    • 集成框架的開發人員的優勢是了解框架元素的結構和組合。有些框架,例如 Ruby on Rails,能夠生成測試用例,而且在默認情況下提供測試特性。

    • 具有高級元編程(metaprogramming)能力的語言,例如 Ruby and Lisp,允許使用其他語言不支持的一些測試技巧,例如更容易訪問 mock 對象。

    在這一篇和下一篇文章中,將全面理解在 Ruby on Rails 集成開發框架中的測試方式。第 1 部分側重于測試模型對象,并提供一些從 Rails 獲得啟發的策略,可以用這些策略使 Java 單元測試更有效。第 2 部分把更多時間花在功能測試和集成測試上。作為 Java 程序員,您對一些概念可能比較熟悉,特別是在測試的時候,而其他一些概念可以拓展您的理解。





    回頁首


    補漏

    在這個系列的 前一期 中,了解了動態類型化會帶來某些 bug 種類,靜態類型化語言將在編譯時捕捉到這些 bug。清單 1 的 Ruby 代碼片段包含四個不同的 bug,這四個 bug 在運行時之前都不會顯露出來:


    清單 1. 帶 bug 的 Ruby 代碼
                position = "2"               #string, where a number was intended
                position = positoin + 4      #position is misspelled, evaluates to 0
                puts "The position is:" +
                position.to_string     #The method should be to_s
                

    如果編譯器能夠捕捉 bug,那么這類 bug 解決起來是小菜一碟,但是如果依賴解釋器,那么管理這些 bug 就困難得多。為了處理這些微妙的錯誤,動態語言的用戶長期以來一直依賴于自動測試。在進行測試的時候,比起其他語言,動態語言及其集成環境在一般意義和特殊意義上都具有顯著的優勢:

    • 語言更簡潔。測試基本上是腳本編程,許多最好的腳本語言都是動態類型化的。

    • 集成環境支持的假設可以讓集成測試更容易,也可能更強大。在 Rails 環境中將看到一些示例。

    • 動態語言允許使用更松散的耦合,使一些測試格式更容易實現。

    在了解動態語言開發人員為什么這么熱衷于測試之后,現在是構建一個需要一些真正測試的實際應用程序的時候了。





    回頁首


    構建一個快速 Rails 應用程序

    為了進展得快些,我采用了一個保存山地摩托車路線數據庫的 Rails 應用程序。我將模型的幾個測試放在一起。如果想和我一起編寫代碼,那么所有需要的工具就是一個數據庫引擎(我使用的是 MySQL)和 Ruby on Rails 1.1 或更新版本(請參閱 參考資料)。第一步是創建 Rails 項目。在命令提示符下輸入 rails trails 命令,清單 2 顯示了命令和結果:


    清單 2. 構建 Rails 應用程序
                > rails trails
                create
                create  app/controllers
                create  app/helpers
                create  app/models
                create  app/views/layouts
                ...partial results deleted...
                create  test/fixtures
                create  test/functional
                create  test/integration
                create  test/mocks/development
                create  test/mocks/test
                create  test/unit
                create  test/test_helper.rb
                ...partial results deleted...
                create  config/environment.rb
                create  config/environments/production.rb
                create  config/environments/development.rb
                create  config/environments/test.rb
                ...partial results deleted...
                create  log/server.log
                create  log/production.log
                create  log/development.log
                create  log/test.log
                

    Rails 除了生成空項目什么都沒做,但是可以看到它正在為您工作。清單 2 創建的目錄中包含:

    • 應用程序目錄,包括模型、視圖和控制器的子目錄
    • 單元測試、功能測試和集成測試的測試目錄
    • 為測試而明確創建的環境
    • 測試用例結果的日志

    因為 Rails 是一個集成環境,所以它可以假設組織測試框架的最佳方式。Rails 也能生成默認測試用例,后面將會看到。

    現在要通過遷移創建數據庫表,然后用數據庫表創建新數據庫。請鍵入 cd trails 進入 trails 目錄。然后生成一個模型和遷移(migration),如清單 3 所示:


    清單 3. 生成一個模型和遷移
                > script/generate model Trail
                exists  app/models/
                exists  test/unit/
                exists  test/fixtures/
                create  app/models/trail.rb
                create  test/unit/trail_test.rb
                create  test/fixtures/trails.yml
                create  db/migrate
                create  db/migrate/001_create_trails.rb
                

    注意,如果使用 Windows,就必須在命令前加上 Ruby,這樣命令就變成了 ruby script/generate model Trail。

    如清單 3 所示,Rails 環境不僅創建了模型,還創建了遷移、測試用例和測試 fixture。稍后將看到 fixture 和測試的更多內容。遷移讓 Rails 開發人員可以在整個開發過程中處理數據庫表中不可避免的更改(請參閱 跨越邊界:研究活動記錄)。請編輯您的遷移(在 001_create_trails.rb 中),以添加需要的列,如清單 4 所示:


    清單 4. 添加列
                class CreateTrails < ActiveRecord::Migration
                def self.up
                create_table :trails do |t|
                t.column :name, :string
                t.column :description, :text
                t.column :difficulty, :string
                end
                end
                def self.down
                drop_table :trails
                end
                end
                

    您需要創建和配置兩個數據庫:trails_testtrails_development。如果想把這個代碼投入生產,那么還需要創建第三個數據庫 trails_production,但是現在可以跳過這一步。請用數據庫管理器創建數據庫。我使用的是 MySQL:


    清單 5. 創建開發和測試數據庫
    mysql> create database trails_development;
                Query OK, 1 row affected (0.00 sec)
                mysql> create database trails_test;
                Query OK, 1 row affected (0.00 sec)
                

    然后編輯 config/database.yml 中的配置,以反映數據庫的優先選擇。我的配置看起來像這樣:


    清單 6. 將數據庫適配器添加到配置中
    development:
                adapter: mysql
                database: trails_development
                username: root
                password:
                host: localhost
                test:
                adapter: mysql
                database: trails_test
                username: root
                password:
                host: localhost
                

    現在可以運行遷移,然后把應用程序剩下的部分搭建(scaffold)在一起:


    清單 7. 遷移和搭建
    > rake migrate
                ...results deleted...
                > script/generate scaffold Trail Trails
                ...results deleted...
                create  app/views/trails
                ...results deleted...
                create  app/views/trails/_form.rhtml
                create  app/views/trails/list.rhtml
                create  app/views/trails/show.rhtml
                create  app/views/trails/new.rhtml
                create  app/views/trails/edit.rhtml
                create  app/controllers/trails_controller.rb
                create  test/functional/trails_controller_test.rb
                ...results deleted...
                

    再次注意,Rails 已經為您創建了測試用例?蚣懿粌H為這個簡單的小程序生成了視圖和控制器,而且還生成了有助于測試用戶界面的功能性測試。





    回頁首


    對 Rails 應用程序進行單元測試

    現在是運行一些測試的時候了。請看第一個測試,它已經在 test/unit/trail_test.rb 中寫好了:


    清單 8. 第一個測試
    require File.dirname(__FILE__) + '/../test_helper'
                class TrailTest < Test::Unit::TestCase
                fixtures :trails
                # Replace this with your real tests.
                def test_truth
                assert true
                end
                end
                

    確實,這個測試用例算不了什么,但您可以從中看出如何構架測試代碼,而且自己的測試用例的模板也已經就位。請運行測試,如清單 9 所示(包括結果):


    清單 9. 運行第一個測試
    > ruby test/unit/trail_test.rb
                Loaded suite test/unit/trail_test
                Started
                EE
                Finished in 0.027314 seconds.
                1) Error:
                test_truth(TrailTest):
                ActiveRecord::StatementInvalid: Mysql::Error: #42S02Table
                'trails_test.trails' doesn't exist: DELETE FROM trails
                ...results deleted...
                

    測試用例失敗,但是請看輸出。第一行執行測試。第三行 EE 顯示測試的結果。如果測試用例通過,會得到 “.” 字符。如果測試用例產生錯誤,會看到 E。如果某個斷言不是 true,那么將看到 F。接下來,可以看到所請求的全部測試都將完成,以及完成這些測試需要的時間。最后,將看到每個失敗的詳細原因。在這個示例中沒有表,這是有一定原因的,因為在測試數據庫中還沒有創建任何表。通過將開發方案復制到測試環境,再重新運行測試,可以修復錯誤,如清單 10 所示:


    清單 10. 復制方案,重新運行測試
    > rake clone_schema_to_test          (in /Users/batate/rails/trails)
                > ruby test/unit/trail_test.rb
                Loaded suite test/unit/trail_test
                Started
                .
                Finished in 0.038578 seconds.
                1 tests, 1 assertions, 0 failures, 0 errors
                

    這樣更好。但是測試還是太簡單,所以是構建一個真正的測試用例的時候了。請添加下面這個新測試用例 test_truth,如清單 11 所示:


    清單 11. 添加測試用例
        def test_truth
                assert true
                end
                def test_new
                trails = Trail.find_all
                Trail.new do |trail|
                trail.name = "Barton Creek"
                trail.description = "A little water in the Spring. You'll get wet."
                trail.difficulty = "medium"
                trail.save
                end
                bc = Trail.find_by_name("Barton Creek")
                assert_equal "medium", bc.difficulty
                assert_equal trails.size + 1, Trail.find_all.size
                end
                

    這個代碼驚人的緊湊。只需要鍵入上述代碼以及兩個斷言,就可以操縱持久模型。這種經濟的投入正是腳本語言在其他環境中如此流行的原因。測試也是需要經濟投入的地方。

    現在可以運行測試用例,您將看到兩個新斷言顯示在測試報告中。使用 Ruby 時,只需保存并編譯測試即可。清單 12 顯示了測試運行的結果:


    清單 12. 測試結果
    > ruby test/unit/trail_test.rb
                Loaded suite test/unit/trail_test
                Started
                .
                Finished in 0.038578 seconds.
                1 tests, 1 assertions, 0 failures, 0 errors
                bruce-tates-computer:~/rails/trails batate$ ruby test/unit/trail_test.rb
                Loaded suite test/unit/trail_test
                Started
                ..
                Finished in 0.182043 seconds.
                2 tests, 3 assertions, 0 failures, 0 errors
                

    Fixture 和回滾

    Java mock 對象

    在解決測試數據庫支持代碼的困擾時,Java 開發人員經常使用 mock 對象而不是實際的數據庫代碼。Mock 對象設置起來比較難,通常難于理解,而且對于在數據庫環境中工作的代碼,也無法提供良好的理解。Ruby on Rails 支持不同的方式。

    有三個問題影響了對數據庫支持代碼的測試。它們都與兩個特性有關:性能和重復性。與內存中的操作相比較,數據庫調用的性能是非常低的。如果測試運行需要太長時間,那么您可能就不想運行它們了。另一個問題是一個測試用例對另一個測試用例的影響。因為數據庫調用在性質上是持續的,所以要把一個測試在數據庫中的變化與另一個數據庫中的隔離開。最后的問題是前兩個問題的組合。為了讓數據庫測試用例可重復而增加設置和拆卸的負擔時(為每個新的測試用例添加記錄、運行測試并刪除這些記錄),帶來的開銷可能是讓人無法接受的。與這種開銷相比,測試用例開銷簡直是小巫見大巫。

    Ruby on Rails 用 fixture 和事務回滾來幫助解決這些問題。在 Rails 中,一個 fixture 就是一個包含測試用例數據的文件。在創建這個簡單應用程序時,同時還創建了一個開發數據庫和一個測試數據庫。創建開發數據庫是很正常的;但是您可能不想讓生產代碼和開發環境共享同一個數據庫。而創建測試數據庫因為另一個原因也很重要。每個測試都在測試用例開始時裝入 fixture 中的測試數據。然后,測試用例對數據庫進行修改,并測試這些修改的結果。最后,Rails 回滾這些變化,將數據庫返回到測試方法運行之前的狀態。

    現在要制作一個測試 fixture 并為它編寫一個測試。請編輯 test/fixtures/trails.yml 文件,添加一個記錄,如清單 13 所示:


    清單 13. 添加記錄
        first:
                id: 1
                name: "Emma Long"
                description: "A real bike breaker."
                difficulty: "hard"
                another:
                id: 2
                name: "Bear Creek"
                description: "Too many downed trees."
                difficulty: "easy"
                

    清單 13 使用叫做 YAML 的語言,這個語言描述結構化的數據(請參閱 參考資料)。此文件對空格很敏感,所以該當用空格代替制表符并完全按原樣鍵入數據項時,請確保刪除了所有尾部空格。

    同樣,還要把這個測試用例添加到 trails_test.rb 中:

        def test_find
                assert_equal "Emma Long", Trail.find(1).name
                assert_equal "easy", Trail.find(2).difficulty
                end
                

    同樣,可以用 5 個 passing 斷言運行這些測試。如果您愿意,還可以按名稱引用每個 fixture。例如,要根據名為 first 的 fixture 來創建對象,可以使用 Ruby 代碼 trails[:first]。讓 fixture 對所有測試用例或只對需要它們的測試用例可用,這極大地簡化了創建或毀壞數據庫數據所需要的代碼。





    回頁首


    在 Java 編程中測試

    知道了測試在其他語言中如何發生,就可以改進在 Java 平臺上進行測試的方式。具體地說,使用這些想法中的一項或多項可以對測試產生顯著而直接的影響:

    • 可以把測試用例的生成添加到任何現有代碼生成當中。Ruby on Rails 通過在默認情況下創建一些簡單的測試用例來取得了巨大優勢,您也可以這么做。

    • 可以用事務-回滾技術讓數據支持的測試運行得更快。Spring 框架有一些現有的攔截器,可以讓這項技術易于使用。

    • 實際上可以用動態語言驅動測試。Jython、Ruby 和 Groovy 是三個實際可能。

    如果覺得愿意采用其他語言進行測試,那么可以使用某種 JVM 語言,例如 JRuby(請參閱 參考資料)。JRuby 還沒有高級到可以運行 Ruby on Rails,但是它是 Java 應用程序卓越的測試平臺。只是作為嘗試,JRuby 的開發人員 Charles O'Nutter 提供了以下測試 EJB 的示例:


    清單 14. 用 JRuby 測試 EJB 組件
        require 'test/unit'
                require 'java'
                include_class "my.pkg.EJBHomeFactory"
                class TestMyBean < Test::Unit::TestCase
                def test_finder
                wh = EJBHomeFactory.widget_home
                w = wh.find_by_color("blue")
                assert_not_nil(w)
                end
                def test_widget
                wh = EJBHomeFactory.widget_home
                w = wh.find_by_name ("superWidget")
                assert_equal("blue", w.color)
                assert_equal(14, w.id)
                end
                end
                

    可以看到,用 Ruby 編寫執行 Java 代碼的測試用例實際上非常容易。在這個示例中,Ruby 代碼發現一個 EJB 組件,并為用戶返回的 bean 提供了一些斷言。測試用例當然比多數 Java 測試都容易,使用 Ruby 編寫測試用例是一個獲得更高的生產率和速率的一種好方法。我還看到針對 Jython 或 Groovy 的類似策略(請參閱 參考資料)。

    第 2 部分將進一步深入查看 Rails 的測試,包括運行更高層次測試(叫做功能測試和集成測試)的代碼。

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>