本文章是由機器翻譯。

.NET Interop

使用者入門使用 IronRuby 及 RSpec,第一部

Ben Hall

本文根據 IronRuby 的搶鮮版所撰寫。 所有的資訊有變更。

本文將告訴您:
  • [注音標示] 和 duck 型別
  • [注音標示]] 和 [Microsoft.NET Framework
  • 使用 IronRuby 和 RSpec
本文將使用下列技術:
IronRuby

可從 MSDN 程式庫 的程式碼下載
瀏覽線上的程式碼

內容

在程式碼中,定義需求] 和 [範例
[注音標示] 和 duck 型別
拼音及 MetaProgramming
[注音標示] 和.NET Framework
[注音標示] 和 CLR
內部 IronRuby
測試一個 C# 應用程式,與 IronRuby
向前移動

「 那沒有我們要求的 ! 」 我相信大多數的開發人員已經聽說不久後提供最新的組建的這個從客戶的口號。 客戶可能會 yelling 不良的開發人員基於各種原因,可能需求不正確地瞭解或系統的一部分只做無法運作。

因為通常不清楚,以自己的需求客戶他們將會選擇嘗試定義所有系統可能只需要在 100 頁技術文件的安全性。 同時,開發人員 struggles,嘗試瞭解如何在應用程式要嘗試實作新的需求,而不中斷任何工作的記載舊碼。

變更時間。 軟體開發的新方法被要略解決協助您以符合在第一次嘗試客戶需求,而不會在處理序中造成失敗的這些問題。 這些方法利用語言 (例如,讓您建立輕鬆地讀取及維護的程式碼,以更短的開發反覆項目 [注音標示]。

本文,我將為您介紹 [注音標示] 和 [IronRuby,並示範的拼音與 Microsoft.NET Framework 為基礎的程式碼互通的一些基本概念。 我也說明如何架構,例如 RSpec 可用來產生範例如何物件用來行為,提供同時說明文件和系統建置在正確的驗證。 這會設定為未來的發行中,我將說明接受度測試詳細資料,和示範與 IronRuby 建立接受度測試階段。

在程式碼中,定義需求] 和 [範例

為了協助撰寫的範例中,並定義需求中,您需要一個架構。 有許多不同的方式撰寫自動化的接受度測試或可執行檔的規格。 有些人使用的標準 xUnit 測試架構成功,而其他人使用符合與架構。 我已經找到最好的方法是使用行為的驅動程式開發 (BDD)。 Dan 北想出一個 BDD Framework 呼叫 JBehave 做為定義案例描述,可以溝通整個小組不論技術的能力的應用程式的行為方式。

北美面臨與測試導向開發 (TDD) 及實作 Java 語言有問題的結果 JBehave。 之後,北會建立之後已經整合至 RSpec,[注音標示] 的常見架構的 RBehave。 RSpec 適用於 BDD 的兩種不同方法: 根據新聞和案例,以描述應用程式的行為的 Dan 北邊的方法和 Dave Astels ' 方法的更著重於在物件層級建立範例。

C# 有一些例如 NSpec 和 NBehave 的 BDD 架構。 在 C# 中撰寫測試,主要問題是 true 表示測試的目的通常因為到您有額外的結構化的項目與中繼資料例如大括號公開和私密的事實隱藏中。 整體,我不認為提供透過 C# 是,而且 NSpec / NBehave 器 」 可以符合是可透過 IronRuby 和 RSpec。 先前,這就已經主要的問題,C# 開發人員,您無法不具有使用 Ruby-基礎) RSpec 來測試 C# 應用程式。 與 IronRuby,這不再是一個問題。

時仍在早期開發,IronRuby 利用 「 動態語言執行階段 (DLR),以建立 CLR 的上方拼音語言的實作。 與 IronRuby,您可以運用現有的拼音應用程式] 和 [搭配.NET Framework 和.NET 相容語言的架構。 結果是您可以使用拼音的語言和 RSpec 來測試 C# 應用程式 !

為一的語言 [注音標示]。 簡潔可讓您撰寫較少的程式碼,並將它 Express 以更自然方式讓您的程式碼更易於維護 例如,讀取檔案的所有文字行數],並將其寫出至主控台,您會撰寫這:

File.readlines('AboutMicrosoft.txt').map {|line| puts line}

程式碼會開啟 AboutMicrosoft.txt 檔案,並讀取所有行,傳每一行,入 [使用做為參數,然後寫入主控台列區塊。 在 [注音標示],區塊是在大括號之間的陳述式的集合且類似叫用 C#,使用 yield 陳述式,傳回至呼叫的方法的控制項中的方法。

其自然語言的方法會是 [注音標示] 絕佳測試時使用,原因之一。 案例的測試,在此情況下是許多更容易閱讀。

[注音標示] 和 duck 型別

其中一個拼音及動態語言為何更容易閱讀的原因是因為它們如何處理輸入。 而不是開發人員定義型別,拼音的程式碼會中斷時,變數的型別推斷。 語言還強型別,但它會以動態方式判斷變數的型別。

使用 C# 介面允許 decoupling 的物件,同時還定義實作的合約。 使用 [注音標示],沒有必要合約的介面。 如果此物件,方法要呼叫的實作然後它的呼叫。 如果沒有,則傳回的錯誤。 因此,由它的實作不是程式碼的其他部分的關聯性定義物件的合約。

為了示範這,我可以建立方法,可接受的型別將會被推斷在執行階段值。 然後它會輸出 Hello 加上值:

   def SayHello(val)
     puts "Hello #{val}"
   end

因為的型別的處理的方式,您可以而不變更任何程式碼的重複使用相同的字串和整數的方法:

   SayHello("Test") => "Hello Test"
   SayHello(5) => "Hello 5"

我可能也已呼叫方法沒有括弧,這些是 [注音標示] 中的選擇性的並可以會讓語法更更容易閱讀:

   SayHello "Test" => "Hello Test"

這可以在 C# 中使用物件,達成,但我們來看看如何,這會使用更複雜的物件。 我可以定義新的方法,輸出至 GetName 在呼叫的結果。 只要 n 參數的值,實作呼叫 GetName 方法,程式碼將會運作:

def outputName(n)
  puts n.GetName()
end 

以下是兩個不相關的類別:

class Person
  attr_accessor :name
  def GetName()
    @name
  end
end
class Product
  def GetName()
    "The product with no name"
  end
end

連絡人會有設定,而產品會傳回硬式編碼值,讓該名稱的變數的存取子。 在 [注音標示] 中,,沒有需要撰寫,傳回的陳述式,根據預設,會傳回方法的程式碼的最後一行的最後結果。

如果您在呼叫方法) outputName 會呼叫在 GetName 方法,示範如何紅寶石的輸入提高程式碼重複使用性因為我們不是固定單一型別:

outputName(Product.new) => "The product with no name"
$x = Person.new
$x.name = "Ben Hall"
outputName($x) => "Ben Hall"

如果您呼叫使用的引數不實作 GetName 方法,則會引發一個 NoMethodError:

outputName("MyName") => :1:in 'outputName': \
  undefined method 'GetName' \
  for MyName:String (NoMethodError)

這個概念是有關有些人時, 很有用,尤其是當測試在接下來的章節將討論的 C# 應用程式允許改良的 testability 的應用程式的設計中。

拼音及 MetaProgramming

徹底類似其他動態語言,[注音標示] 實行的概念 meta-programming。 這可讓您延伸任何類別或物件執行階段讓您定義的方法和行為執行階段讓您能夠開發 self-modifying 應用程式。 這是在動態語言,尤其是在單元測試,非常有用的因為它可讓您自訂物件和方法,以您自己的需求的行為。

類似方式您可以擴充,內建拼音類別以提供您自己功能,更像 C# 3.0 中的延伸方法。 使用 C# 中,有各種的限制,需您可以建立的方法。 例如,它們必須是靜態和不同的類別。 這全部損害的可讀性。 與 [注音標示],您只建立一般方法,在現有的類別上。 例如,整數會是類別來處理整數。 整數有一系列的方法,但是它並沒有方法來說是否甚至是數。

若要建立這類方法,您只要使用相同名稱 (整數) 中建立新的類別並定義新的方法。 方法結尾處的問號表示,讓它更容易閱讀的目標會傳回布林值 (Boolean):

class Integer
   def even?()
       self.abs % 2 == 0
   end
end
puts 2.even? => true
puts 1.even? => false

[注音標示] 和.NET Framework

代替舊的辯論,有關是否要使用靜態或動態語言,IronRuby 可讓您針對工作使用正確的語言。 如果它會使用 C# 更有意義,您可以使用 C#。 如果您需要以更動態的方法時,您就可以輕鬆地使用 IronRuby,並利用其與.NET 的互通性和拼音的語言的動態性質。 我預期使用的不同語言和技術,(例如,C# 主應用程式和 Ruby,測試混合的使用者。

DLR 會提供以.NET Interop 基礎。 這在位置您可以利用 UI 技術 (例如 Windows Form、 Windows Presentation Foundation (WPF) 和 Silverlight 寫入應用程式的程式碼,在 [注音標示] 時。

利用 WPF 的從 IronRuby 很容易。 當執行下列程式碼,是可以將 WPF 視窗從 IronRuby 建立正常運作。 您仍然必須參考 mscorlib 及兩個 WPF 組件隨附於.NET Framework 3.0 使用 C# 方式使用,需要陳述式:

require 'mscorlib'
require 'PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
require 'PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

您現在可以建立,並與 WPF 物件互動。 先,建立您要使用的所有物件的別名。 這讓程式碼清潔器,因為您不需要存取透過其命名空間的物件:

Window = System::Windows::Window
Application = System::Windows::Application
Button = System::Windows::Controls::Button

接下來,建立 WPF 視窗],並提供標題:

win = Window.new
win.title = 'IronRuby and WPF Interop'

建立按鈕,以相同的方式:

mainButton = Button.new
mainButton.content = 'I'm a WPF button — press me'

在兩個執行個體中我使用別名來存取物件的完整名稱。 當按一下 [] 按鈕時想要使用者顯示一個 MessageBox。 如同在 C# 中,您就可以訂閱事件,並提供區塊時叫用 Click) 事件所呼叫:

mainButton.click do |sender, args|
  System::Windows::MessageBox.Show("Created using IronRuby!")
end

最後,設定 [] 按鈕、 建立新的應用程式物件和啟動視窗],視窗的內容:

win.content = mainButton
my_app = Application.new
my_app.run win

fig01.gif

[圖 1 使用 IronRuby 建立一個 WPF 應用程式

這時候完整互動式 WPF 視窗會顯示與按一下 [事件正確有線上,如 [圖 1 ] 所示。 我互動與.NET Framework,我會互動拼音的程式庫相同的方式。 John Lam 並小組設定出在核心原則之一是保持為 True,拼音的語言。 這是由目前的拼音開發人員,不會想要變更,因為它們移到 IronRuby,它們會建立拼音的應用程式的方式所採用的重要原則。 而它們可以在相同的方式存取所有豐富的.NET 程式碼。

[注音標示] 和 CLR

以下是另一個範例。 如果嘗試存取的 IEnumerable AddRange 在 C# 程式碼如下:

ArrayList list = new ArrayList();
list.AddRange(new [] { 1,2,3,4 });

不過,使用 [注音標示],接受的慣例是的文字內方法的名稱以底線來改善可讀性。 太耗時且容易發生錯誤,建立個別的程式庫来遵循此慣例為,它會在不支援其他的協力廠商開發中。

而的 CLR 物件,IronRuby 轉譯至 CLR 的對等方法名稱的拼音的方法呼叫:

   $list = ArrayList.new
   $list.add_range([1,2,3,4])

此處我正在存取 AddRange 方法,下列是與以底線字元分隔的文字的大小寫的紅寶石的方法。 如果您希望,您可以將使用 CLR 的命名慣例如方法名稱存在從 [注音標示]:

$list.AddRange([1,2,3,4])

作用都,作用相同,只是個人的偏好使用的。

如我所述,[注音標示] 在執行階段推斷物件的型別而這是在相同處理 C# 物件時。 請考慮一系列的會傳回不同的物件型別時,會傳回相同的物件,方法簽名碼傳回介面或具象型別的 C# 方法。 我的範例中,我有定義單一的 HelloWorld 方法的介面:

public interface IHello {
  string HelloWorld();    
}

我建立一個 Hello4Times 類別繼承自 Hello3Times 繼承自介面,但已實作三個額外的 Hello­World 方法。 在類別中我會定義稱為 HelloMethodOn4Times 呼叫基底實作的新方法:

public class Hello4Times : Hello3Times {
  public string HelloMethodOn4Times () {
    return base.HelloWorld();
  }
}

我接著會定義靜態類別和方法,將會傳回 Hello4Times 類別的新執行個體,但傳回它為介面呼叫的程式碼。 這表示呼叫程式碼應該只知道 HelloWorld 不會有任何其他方法定義:

public static class HelloWorld {
  public static IHello ReturnHello4TimesAsInterface() {
    return new Hello4Times();
  }

在我拼音的程式碼中,我有兩個方法呼叫。 第一個呼叫會位於您會想不問題需要定義介面方法。 不過,第二次呼叫會是至具體類別上的方法。 IronRuby 判斷在物件所傳回的型別,並可以分派方法呼叫:

puts InteropSample::HelloWorld.ReturnHello4TimesAsInterface.HelloWorld
puts interopSample::HelloWorld.ReturnHello4TimesAsInterface.HelloMethodOn4Times

所有這些都發生沒有您需要擔心轉型正確呼叫方法的型別之物件。

此的佈景主題下列您可以在拼音物件您可以擴充以完全相同的方式.NET 物件。 顯示在 MessageBox 時, 我不想保留定義的圖示和按鈕來使用。 而,我只是要提供訊息。

或許您也沒有像內建的功能,而且想要擴充實際的 MessageBox 類別的無接縫互動。 使用 [注音標示],這很簡單。 您定義新的類別在 WPF 中建置 MessageBox 為相同的。 您然後會建立只會呼叫以各種不同的預設值顯示方法之類別的新方法:

class System::Windows::MessageBox
  def self.ShowMessage(msg)
    System::Windows::MessageBox.Show(msg, msg, \
      System::Windows::MessageBoxButton.OK, \
      System::Windows::MessageBoxImage.Stop)
  end
end

執行這個程式碼區塊之後

System::Windows::MessageBox.ShowMessage( \
  "I'm going to show you a message") 

您可以呼叫 ShowMessage 方法的訊息方塊中顯示結果 [圖 2] .

fig02.gif

[圖 2 顯示在自訂 MessageBox,從紅寶石

內部 IronRuby

Interop 的可能是如何呢? 答案是,DLR 時。 高層級當您執行使用 IronRuby 的拼音程式碼許多的工作會會在幕後的發生。 先,您撰寫程式碼是會 tokenized,並剖析 IronRuby 引擎。 剖析的程式碼接著會轉換成 DLR 的抽象語法樹狀目錄 (AST) 中。 這是標準化的 AST 所有語言實作如 IronPython,DLR 提供以執行程式碼所都需要的。

DLR 一旦將 AST 它會將樹狀結構轉換成中繼語言 (IL) 中。 所有的.NET 程式碼) 下編譯,成 IL,CLR 提供一種泛用的語言。 這是 IronRuby 可以與.NET Framework 互通的方式 — 在幕後為 IL 指示執行所有程式碼。 DLR 完成轉換後,會將 IL 傳遞至 CLR 執行,並 IronRuby 到會傳回結果。

在這個過程中,有其他步驟,以改善效能和可靠性例如快取。 如需更深入的說明,我建議讀取出資料行內的 Bill Chiles CLR 」 Iron­Python 和動態語言執行階段「 在 10 月) 2007 中發行的 MSDN Magazine .

在不同的組件內有是裝載 API,可讓您將 IronRuby 內嵌在您自己的應用程式,可讓您從 C# 或使用者執行自己的程式碼執行拼音的程式碼。

如需詳細資訊,IronRuby 實作中,,下載從整個原始程式碼 RubyForge. IronRuby 會是在 C# 中實作的開放原始碼專案,而且是一個動態語言實作的最佳範例。 IronPython 是可用 (因為 CodePlex,和它所裝載的開放原始碼專案會包含範例的語言,如果您要到 DLR 的運作方式的介紹,請呼叫 ToyScript)。

若要確保可繼續使用核心拼音平台的相容,IronRuby 小組使用 RubySpecs。 這是一套串共用周圍應該如何實作拼音的語言為基礎的範例。 RubySpecs 的目標是確保包括 Matz 的拼音解譯器 (MRI) 的不同實作,JRuby 」、 「 MacRuby 和 「 IronRuby 有在相同的行為。 RubySpecs 會使用 RSpec 呼叫 MSpec 語法-相容版本。 這些會視為 IronRuby 實作接受度測試。

測試一個 C# 應用程式,與 IronRuby

現在許多年,感知 」 和 「 TDD 的作法有增加以開發產生高品質,在方面的程式碼設計和可維護性與較少的缺失,以及在方法一起的軟體。 IronRuby,我可以使用 Runner 與 RSpec 規格 Framework,提供範例的方式 [我的 C# 物件工作,下列 BDD 方法,而不是 TDD。

雖然我在日後的文章會介紹的 Framework 案例更與接受度測試在應用程式層級對齊,Framework 更對齊開發人員撰寫自己的規格,程式碼在規格它們是幾乎實作,其預期的行為。 解決提供描述在物件層級行為的範例是以 Framework 規格為基礎。 這些範例可以執行,以確認系統的實作仍運作,開發人員必須同時提供如何在物件預期行為的相關文件。

這是與單元測試架構,例如 NUnit 和 MbUnit 比較的重要差異。 這兩個使用測試屬性,表示方法是系統的測試。 RSpec 會了不同的方法。 RSpec 會指出每個方法是如何在程式碼用來工作範例。 差異細微時它就會變更您撰寫的範例包括您使用,在您在組織的方法 」 和 「 如何輕易地概念可以瞭解 TDD 來比較的方式,術語,方式。 BDD 與 RSpec,和 IronRuby 關閉的整合與 [NET 即可開始使用 IronRuby 來測試 C# 應用程式。 範例,方面的傳統 RSpec 範例是保齡球遊戲)。

首先,您需要存取保齡球遊戲的實作,在 C# 組件中:

require File.dirname(__FILE__) + \
  '/InteropSamples/Bowling/Bowling/bin/Debug/bowling.dll'

然後您需要存取 RSpec:

require 'rubygems'
require 'spec'

現在您可以開始撰寫範例。 這是顯示 bowling 實作應該運作方式的範例。 RSpec 會有一個網域特定語言 (DSL) 對於範例為可執行檔必須遵守您。 第一個部分中的是 DSL 的在描述區塊。 這裡您只要狀態,您的 「 描述的物件 」 搭配的選擇性描述。 在這種情況下,我定義在保齡球] 物件,將會在 C# 中實作:

describe Bowling, " defines the bowling game" do

若要改善可讀性,任何安裝程式將執行在一個區塊之前:

  before(:each) do  
    @bowling = Bowling.new 
  End

我現在是在與物件互動,建立此範例,並確認它運作正確的位置。 我使用 「 它 」 區塊,提供說明的範例,並在它會示範內容的字串。 然後,我撰寫與系統互動,並驗證正確的動作發生的程式碼區段:

  it "should score 0 for a gutter game" do
    20.times { @bowling.hit(0) }
    @bowling.score.should == 0
  end
end

C# 實作只是起來如下:

public class Bowling {
  public int Score { get; set; }
  public void Hit(int pins)
    { Score += pins; }
}

最後,執行此確認保齡球範例運作如預期般使用 RSpec 測試 C# 物件:

>ir bowling_spec.rb
.
Finished in 1.0458315 seconds
1 example, 0 failures

如果我希望更詳細的報告,我無法選取要 specdoc 格式。 此輸出物件一起使用的所有範例,指出是否它們已傳遞或不描述:

>ir bowling_spec.rb --format specdoc
Bowling defines the bowling game
- should score 0 for a gutter game
Finished in 1.43728 seconds
1 example, 0 failures

在撰寫之時 IronRuby 小組會不定期傳送二進位碼檔案。 小組有說,它正在等候直到滿意實作、 相容性和正式的二進位碼檔案的發行前的效能。 不過,因為原始程式碼自由地使用,您可以下載程式碼,並自行建置它。

如果要下載原始程式碼,您將需要 git 來源控制項用戶例如 msysgit安裝。 IronRuby 專案網站 或我的部落格內容 從 GitHub 下載 IronRuby." 在您下載原始程式碼後您可以編譯組件使用 Visual Studio 中使用 IronRuby.sln 方案檔或者,如果您安裝的 MRI 然後您可以使用命令:

rake compile

一旦您有了 IronRuby 編譯時,您必須下載例如 RSpec,來取得額外的功能的各種程式庫。 [注音標示] 有概念的精華的套件的 RubyGems 您可以下載功能和其他相依性。 如果要下載 RSpec,請在命令提示字元中輸入下列:

gem install rspec

您現在能夠存取您拼音的程式碼從 RSpec Library。 不過,在撰寫之時 RSpec 會無法使用 IronRuby 因為到一或兩個錯誤。 希望時這個公佈 RSpec 應該使用 IronRuby。 若要尋找 RSpec 支援的狀態,請參閱 RSpec 網站IronRuby 郵寄清單.

如果 Bug 尚未被修正,我做一個 二進位檔與 Bug 修正搭配在位置,RSpec 程式庫. (請注意: 小組已修正問題後,不要使用這個版本)

一旦在位置中有正確的二進位碼檔案,ir.exe 就會就 IronRuby 解譯器可以執行您的程式碼。 如果您只要啟動應用程式,從命令列,您要輸入互動式主控台。 在 [注音標示],則程式碼會在以逐行方式絕佳的學習和偵錯,但也用於執行簡短的命令來解決每日問題上] 執行。 如果您提供做為參數的檔案名稱,則會將檔案) 執行的結果輸出至主控台。

向前移動

我下的文件中,我將介紹接受度測試和如何,它可以改善客戶和開發人員之間的通訊的概念。 我將示範如何可以是接受度測試自動化使用 IronRuby] 和 [RSpec 來確認.NET 應用程式中,並建立系統的可執行檔的規格。

Ben Hall 是在 C# 開發 / 軟體測試人員與一個強式的熱情,軟體開發的而愛上撰寫程式碼。 Ben 運作在英國的紅色的閘道軟體 為測試工程師和樂於探索包括手動和自動化測試,著重於測試不同類型的應用程式最好的方法的測試軟體的不同方式。 Ben 會是 C# MVP,並維護在部落格 Blog.BenHall.Me.uk.