overriding methods?

A

aidy

Hi,

I have a class for each automated test, and each application window or
any other related group of functionality is in a class

Here is an example of a test class

class ST_LTD_6

def initialize
@browser=Browser.new
@app=Login.new
@territory = Territory.new
@window = Window.new
@generics = Generics.new #could we not use mixins here?
@verify = Verify.new #could we not use mixins here or unit tests?
end

def run
begin
p "TESTID: #{self.class}", "TEST DESCRIPTION: Change View Type"
@browser.start_browser
@app.login
@territory.goto_territory_list

@territory.search_territory("GREENLAND", "NUUK", :view => 'Past'
)

@generics.click_search
p "Do a past and set up an end date at least two days before the
test run"
@verify.verify_result("WHATEVER")
rescue => e
puts("TEST FAILED:" + e.message + "\n" + e.backtrace.join("\n"))
ensure
@app.log_out
@window.close_window
end
end
end
test=ST_LTD_6.new
test.run


Now the next test I have will we be exactly the same as this, but on
this method invocation

@territory.search_territory("GREENLAND", "NUUK", :view => 'Past' )


I need to change or in some cases add additional parameters

so

class ST_LTD_7 < ST_LTD_6

@territory.search_territory("GREENLAND", "NUUK", :stream=> 'Sales' )

end


Could someone please point me in the right direction?

Thank You

Aidy
 
A

aidy

Hi Chris,

I have looked at the Pragmatic Ruby book and I think my design could be
wrong. Though I know I can override a method in a module.

This what I have:


module Territory
def search_territory(country, depot, rest={})
$ie.select_list( :name, 'criteria.countryId').select(country)
$ie.select_list( :name, 'criteria.depotId').select(depot)
$ie.select_list( :name, 'criteria.lob').select(rest[:lob])if
rest[:lob]
$ie.select_list( :name,
'criteria.territoryType').select(rest[:territory])if rest[:territory]
$ie.select_list( :name, 'criteria.viewType').select(rest[:view])if
rest[:view]
end
end


The superclass


class ST_LTD_6

def run
begin
login('aidy', '12345')
.........
search_territory("GREENLAND", "NUUK", :view => "Past")
.......
rescue => e
puts("TEST FAILED:" + e.message + "\n" + e.backtrace.join("\n"))
ensure
log_out
close_window
end
end
end

the base class

class ST_LTD_7 < ST_LTD_6

def run
super # call this method in the supercalss
search_territory("GREENLAND", "NUUK", :view=> 'All')
end
end

test=ST_LTD_7.new
test.run

Now, I have put your code in #run, because the way I interpret it, if
it goes in #initialize as soon as the object is created that method
will be invoked.

If I run the method in ST_LTD_7, what seems to happen is that the
#search_territory is invoked from ST_LTD_6 and ST_LTD_7. So in the
A-U-T,
"Past" is chosen in the combo *then* "All". What I am depseratley
trying to avoid is just copying and pasting the code again and making
one change.

Thank You

Aidy
 
D

Daniel Schierbeck

aidy said:
class ST_LTD_6

def run
begin
login('aidy', '12345')
.........
search_territory("GREENLAND", "NUUK", :view => "Past")
.......
rescue => e
puts("TEST FAILED:" + e.message + "\n" + e.backtrace.join("\n"))
ensure
log_out
close_window
end
end
end

On a side note; you do not need the begin/end block within method and
class definitions. This will do the same:

class ST_LTD_6
def run
login('aidy', '12345')
.........
search_territory("GREENLAND", "NUUK", :view => "Past")
.......
rescue => e
puts("TEST FAILED:" + e.message + "\n" + e.backtrace.join("\n"))
ensure
log_out
close_window
end
end


Cheers,
Daniel
 
C

ChrisH

DRY is good so i would:
class ST_LTD_6
def initialize
@a1 = "GREENLAND"
@a2 = "NUUK"
@a3 = "Past"
end
def run
begin
login('aidy', '12345')
.........
search_territory(@a1, @a2, :view => @a3)
.......
rescue => e
puts("TEST FAILED:" + e.message + "\n" + e.backtrace.join("\n"))
ensure
log_out
close_window
end
end
end

the base class

class ST_LTD_7 < ST_LTD_6
def initialize
super #to get the common/default attributes
@a3 = 'All' #set our differing value
end#and delete the now superfluous over-ride of run()
end

test=ST_LTD_7.new
test.run

You of course should use better attribute names 9^)

Also if these parameters are the only difference I would create a
generic test class that take the parameters as arguments to new() and
just instantiate objects with the various test data

Cheers
 
A

aidy

Chris,

You have given me some brilliant ideas and suggestions, and I have
looked at all my books, but I can't understand why these instance
variables appear as nil

class ST_LTD_6
def initialize
@a1 = "GREENLAND"
@a2 = "NUUK"
@a2= "Past"
end
p @a1, @a2, @a2

........
end
test=ST_LTD_6.new

console
ruby 1.8.2 debugger listens on port 2556
nil
nil
nil

Cheers

Aidy
 
C

ChrisH

aidy wrote:
....
class ST_LTD_6
def initialize
@a1 = "GREENLAND"
@a2 = "NUUK"
@a2= "Past"
end
p @a1, @a2, @a2
This statement is executed when the intrepreter is reading
the Class definition, initialize has not been called yet, so the
attributes have not been assigned to yet.

Also note, you have two @a2s there, the last should be @a3 .

Try:
class ST_LTD_6
def initialize
@a1 = "GREENLAND"
@a2 = "NUUK"
@a3= "Past"
end
p @a1, @a2, @a3
def dump
p @a1, @a2, @a3
end
end
test=ST_LTD_6.new
test.dump


You also might try running ruby with the -w option. This turns on all
warnings, which sometimes help point to issues. When I run this code
it warns me the variables are not initialized


Cheers
 
T

ts

C> aidy wrote:
C> ...C> This statement is executed when the intrepreter is reading
C> the Class definition, initialize has not been called yet, so the
C> attributes have not been assigned to yet.

Well, it's not really this.

A class is an object and like any object it can have instance variable,
for example

moulon% cat b.rb
#!/usr/bin/ruby
class A
@a = 12

def self.show
p @a
end

def initialize
@a = 'instance variable'
end

def dump
p @a
end
end

A.show
A.new.dump
moulon%

moulon% ./b.rb
12
"instance variable"
moulon%

The first '@a = 12' is an instance variable for the class A

'@a = "instance variable"' is an instance variable for an instance of A
 
A

aidy

Chris et al

class ST_LTD_7 < ST_LTD_6

def initialize
super #to get the common/default attributes
@a3 = 'All' #set our differing value
end
end
test=ST_LTD_7.new
test.dump

console
"GREENLAND"
"NUUK"
"All"

It's all working. I can't thank you so much. I think I may be on to a
half-decent test automation framework here. But as you mention, I need
to learn about abstracting classes a little more.

Cheers

Aidy
 
C

ChrisH

class ST_LTD_6....
Agreed Guy. It was just clear that Aidy expected the assignment within
initialize to have taken effect.

In your example the attribute is created and assigned to, so of course
it is not NIL

In any case, it has been fun 9^)

Cheers
Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top