使用Ruby实现简单的事物驱动的web应用的教程

2019-09-25 09:44:39王振洲

Ruby 语言具备非常丰富的语法和异常灵活的动态特征,非常适合创建动态 DSL。本文就是利用 Ruby 来创建 51book 面向测试的 DSL。

用 Ruby DSL 实现业务操作
原理

由于 Ruby 是一种动态脚本语言,是解释执行的,它提供了对一段文本进行 “evaluate”执行的方法。也就是说,我们可以提供一段文本(不必是完整的程序),Ruby 就可以在一个特定的上下文中执行它,当然这段文本需要符合 Ruby 的语法。

比如我们有一个文件 bookshop.txt,它包含了如下文本 : login "andy", "pass4you" , 那么怎么执行它呢?首先需要一个上下文,我们可以定义一个类来表示:
清单 1. BookshopDSLBuilder

class BookshopDSLBuilder  
  def self.execute( dsl) 
    builder=new 
    builder.instance_eval(File.read(dsl), dsl)  
  end 
  def login(user=nil,pwd=nil) 
    print user 
    print pwd 
  end 
end

上面的代码非常简单,需要关注的是静态方法 execute, 当把 bookshop.txt 作为参数来调用它时,会有什么情况发生呢 ? 聪明的读者可能已经猜到了,那就是 user 和 pwd 的值会被打印出来。这段代码展示了 Ruby 语言的两个重要特点 :

    instance_eval 方法会把一段文本当做代码来执行。执行的上下文就是对象 BookshopDSLBuilder。 所以当它碰到文本 "login" 时,会自动调用真正的方法 login。
    在调用一个方法时,可以不加括号。这就是为什么 Ruby 会把文本 login "andy","pass4you" 当做一个方法调用的原因。

这两个特点就给我们搭了一座“桥”,使得我们可以把那个面向业务测试的文本诸如“login”,“add_to_cart”,“search_book”等转化为对特定方法的调用了。我们就可以在这些方法中实现某些逻辑。
Watir

我们现在已经能够把业务测试的脚本和 Ruby 的对象 / 方法连接起来,可是还需要第二座桥把 Ruby 和 Web 应用程序连接起来,这样才能使业务测试的脚本驱动 Web 页面进行测试。我们希望能有一个软件或工具可以像人一样来驱动浏览器的操作,例如点击链接,填充表单,点击按钮等等。当然它也可以检查页面的结果,例如期待的文本是否出现等。

开源工具 Watir 就是这样一个工具,除了具备上述功能外,它和 Ruby 语言还能进行无缝的集成,并且对浏览器尤其是 IE 有超强的控制能力。所以我们选取它作为第二座桥。

下面是一个使用 watir 的简单例子,它进入 Google 的首页,在搜索框中键入 "bookshop", 然后点击"搜索"按钮。 Watir 充分继承了 Ruby 语言简单明了的特点,读者可以看到使用 Watir 的脚本是相当直观,相当容易的。
清单 2. Watir 例子

require "watir"
ie = Watir::IE.new 
ie.goto "http://www.google.com"    
ie.text_field(:name, "q").set "bookshop"
ie.button(:name, "btnG").click