与 class 变量一起使用时 class 的未定义方法错误
Undefined method error for a class when used with class variables
我正在使用 ruby 和 watir 测试应用程序。我有一个文件 init.rb,代码为
class Init_Test
def initialize
@browser = Watir::Browser.new :firefox
end
def login_with_creds username,password
@browser.goto 'https://54.69.254.137/webui#/landing'
sleep(2)
@browser.driver.manage.window.maximize
@browser.button(:class => 'sign-in md-button md-default-
theme').when_present.click
sleep(2)
@browser.text_field(:id =>'input_001').set(username)
sleep(2)
@browser.text_field(:id =>'input_002').set(password)
sleep(2)
@browser.button(:class =>'md-primary md-raised md-button md-default-theme').click
sleep(2)
return @browser
end
end
我将这个文件继承到一个名为ann.rb
的文件中
require "watir"
require "watir-webdriver"
require_relative 'init'
class Post < Init_Test
@@b = login_with_creds("abcadmin@example.com","password")
def test_discuss
@@b.input(:id =>'input_002').when_present.click
sleep(1)
@@b.element(aria_label:'What do you want to do?').when_present.click
sleep(1)
@@b.element(:id =>'select_option_00G').when_present.click
sleep(1)
@@b.element(aria_label:'About what?').when_present.click
sleep(1)
@@b.element(:id =>'select_option_00P').when_present.click
sleep(1)
@@b.textarea(:id =>'input_00N').when_present.set('Discuss about java script and later test the application??')
sleep(1)
@@b.span(:text, 'Submit').when_present.click
sleep(1)
end
def test_question
@@b.input(:id =>'input_002').when_present.click
sleep(1)
@@b.element(aria_label:'What do you want to do?').when_present.click
sleep(2)
@@b.element(:id =>'select_option_014').when_present.click
sleep(2)
@@b.element(:id =>'select_017').when_present.click
sleep(1)
@@b.element(:id =>'select_option_01D').when_present.click
sleep(1)
@@b.textarea(:class =>'ng-pristine md-input ng-invalid ng-invalid-
required ng-touched').when_present.set('test question')
sleep(1)
@@b.span(:text, 'Submit').when_present.click
end
end
a = Post.new
a.test_discuss
a.test_question
如您所见,我使用了 class 变量 @@b
并将方法 log_in_creds
分配给它,然后使用 class 变量执行其他活动。但是,当我 运行 它时,它不会为 log_In_creds
抛出任何方法错误
a.rb:6:in `<class:Post>': undefined method `login_with_creds' for
Post:Class (NoMethodError)
from a.rb:4:in `<main>'
为什么它会为 class 变量抛出错误。我需要使用浏览器对象调用每个方法,因为我只想初始化浏览器一次并稍后执行所需的操作。
通常,当您调用 Ruby 方法 (methodA
) 时没有明确的接收者,它与调用 self.methodA
是一样的。根据代码的位置,self
所指的对象可能会发生变化。
class Init_Test
# self refers to Init_Test, a class object
def login_with_creds username,password # define a method for the instances of Init_Test
# self refers to an instance of Init_Test
end
end
现在,在Post
:
class Post < Init_Test
@@b = login_with_creds("abcadmin@example.com","password")
它会尝试用 self
引用 Post
来调用 login_with_creds
,这是一个 class(单例)对象。但是,login_with_creds
被定义为 Init_Test
的所有实例的实例方法,由于继承,它可以在 Post
class 的所有实例上调用。它不适用于 Post
对象或 Init_Test
对象。
此外,在测试中使用class变量共享数据可能容易出错。一个测试的状态可能会影响另一个测试的结果,使得测试不是孤立的。
您可以将其重写为
class Post < Init_Test
def initialize
super
@b = login_with_creds("abcadmin@example.com","password")
end
def test_discuss
@b.input(:id =>'input_002').when_present.click
sleep(1)
...
end
def test_question
@b.input(:id =>'input_002').when_present.click
sleep(1)
...
end
end
a = Post.new
a.test_discuss
a = Post.new # ensure clean state
a.test_question
我正在使用 ruby 和 watir 测试应用程序。我有一个文件 init.rb,代码为
class Init_Test
def initialize
@browser = Watir::Browser.new :firefox
end
def login_with_creds username,password
@browser.goto 'https://54.69.254.137/webui#/landing'
sleep(2)
@browser.driver.manage.window.maximize
@browser.button(:class => 'sign-in md-button md-default-
theme').when_present.click
sleep(2)
@browser.text_field(:id =>'input_001').set(username)
sleep(2)
@browser.text_field(:id =>'input_002').set(password)
sleep(2)
@browser.button(:class =>'md-primary md-raised md-button md-default-theme').click
sleep(2)
return @browser
end
end
我将这个文件继承到一个名为ann.rb
的文件中require "watir"
require "watir-webdriver"
require_relative 'init'
class Post < Init_Test
@@b = login_with_creds("abcadmin@example.com","password")
def test_discuss
@@b.input(:id =>'input_002').when_present.click
sleep(1)
@@b.element(aria_label:'What do you want to do?').when_present.click
sleep(1)
@@b.element(:id =>'select_option_00G').when_present.click
sleep(1)
@@b.element(aria_label:'About what?').when_present.click
sleep(1)
@@b.element(:id =>'select_option_00P').when_present.click
sleep(1)
@@b.textarea(:id =>'input_00N').when_present.set('Discuss about java script and later test the application??')
sleep(1)
@@b.span(:text, 'Submit').when_present.click
sleep(1)
end
def test_question
@@b.input(:id =>'input_002').when_present.click
sleep(1)
@@b.element(aria_label:'What do you want to do?').when_present.click
sleep(2)
@@b.element(:id =>'select_option_014').when_present.click
sleep(2)
@@b.element(:id =>'select_017').when_present.click
sleep(1)
@@b.element(:id =>'select_option_01D').when_present.click
sleep(1)
@@b.textarea(:class =>'ng-pristine md-input ng-invalid ng-invalid-
required ng-touched').when_present.set('test question')
sleep(1)
@@b.span(:text, 'Submit').when_present.click
end
end
a = Post.new
a.test_discuss
a.test_question
如您所见,我使用了 class 变量 @@b
并将方法 log_in_creds
分配给它,然后使用 class 变量执行其他活动。但是,当我 运行 它时,它不会为 log_In_creds
a.rb:6:in `<class:Post>': undefined method `login_with_creds' for
Post:Class (NoMethodError)
from a.rb:4:in `<main>'
为什么它会为 class 变量抛出错误。我需要使用浏览器对象调用每个方法,因为我只想初始化浏览器一次并稍后执行所需的操作。
通常,当您调用 Ruby 方法 (methodA
) 时没有明确的接收者,它与调用 self.methodA
是一样的。根据代码的位置,self
所指的对象可能会发生变化。
class Init_Test
# self refers to Init_Test, a class object
def login_with_creds username,password # define a method for the instances of Init_Test
# self refers to an instance of Init_Test
end
end
现在,在Post
:
class Post < Init_Test
@@b = login_with_creds("abcadmin@example.com","password")
它会尝试用 self
引用 Post
来调用 login_with_creds
,这是一个 class(单例)对象。但是,login_with_creds
被定义为 Init_Test
的所有实例的实例方法,由于继承,它可以在 Post
class 的所有实例上调用。它不适用于 Post
对象或 Init_Test
对象。
此外,在测试中使用class变量共享数据可能容易出错。一个测试的状态可能会影响另一个测试的结果,使得测试不是孤立的。
您可以将其重写为
class Post < Init_Test
def initialize
super
@b = login_with_creds("abcadmin@example.com","password")
end
def test_discuss
@b.input(:id =>'input_002').when_present.click
sleep(1)
...
end
def test_question
@b.input(:id =>'input_002').when_present.click
sleep(1)
...
end
end
a = Post.new
a.test_discuss
a = Post.new # ensure clean state
a.test_question