rutema_web 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..")
2
+ require 'ruport/acts_as_reportable'
3
+ module Rutema
4
+ module UI
5
+ # Formats the test scenario data into a vertical folding structure
6
+ class VerticalTableFormatter < Ruport::Formatter::HTML
7
+
8
+ renders :vhtml, :for => Ruport::Controller::Table
9
+
10
+ def build_table_body
11
+ data.each do |row|
12
+ build_row(row)
13
+ end
14
+ end
15
+
16
+ def build_table_header
17
+ end
18
+
19
+ def build_table_footer
20
+ end
21
+
22
+ def build_row(data = self.data)
23
+ output << "<table class=\"vtable\"><colgroup><col width=\"100\"><col></colgroup>\n"
24
+ output << "<tr><td>#{data['status']}</td><td colspan=\"2\"><h3>#{data['number']} - #{data['name']}</h3></td></tr>"
25
+ output << "<tr><td>duration:</td><td>#{data['duration']}</td></tr>\n"
26
+ %w(output error).each { |k| output << "<tr><td colspan=\"2\"><div class=\"scenario_#{k}\"><pre>#{data.get(k)}</pre></div></td></tr>\n" if data.get(k).size > 0 }
27
+ output << "</table>\n"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,467 @@
1
+ # Copyright (c) 2008 Vassilis Rizopoulos. All rights reserved.
2
+ $:.unshift File.join(File.dirname(__FILE__),"..")
3
+ require 'sinatra/base'
4
+ require 'erb'
5
+ require 'patir/configuration'
6
+ require 'patir/command'
7
+ require 'patir/base'
8
+ require 'rutema_web/model'
9
+ require 'rutema_web/ruport_formatter'
10
+
11
+ module RutemaWeb
12
+ module UI
13
+ #Helper methods that create HTML snippets
14
+ module ViewUtilities
15
+ #image filename to use for succesfull scenarios
16
+ IMG_SCE_OK="/images/run_ok.png"
17
+ #image filename to use for failed scenarios
18
+ IMG_SCE_ERROR="/images/run_error.png"
19
+ #image filename to use for unexecuted scenarios
20
+ IMG_SCE_WARN="/images/run_warn.png"
21
+ #image filename to use for succesfull steps
22
+ IMG_STEP_OK="/images/step_ok.png"
23
+ #image filename to use for failed steps
24
+ IMG_STEP_ERROR="/images/step_error.png"
25
+ #image filename to use for unexecuted steps
26
+ IMG_STEP_WARN="/images/step_warn.png"
27
+ #Time format to use for the start and stop times
28
+ TIME_FORMAT="%d/%m/%Y\n%H:%M:%S"
29
+ #The left arrow
30
+ IMG_LEFT="/images/left.png"
31
+ #The right arrow
32
+ IMG_RIGHT="images/right.png"
33
+ # returns the image tag appropriate for the given status
34
+ def status_icon status
35
+ return case status
36
+ when :warning ,"not_executed"
37
+ "<img src=\"#{IMG_STEP_WARN}\" align=\"center\"/>"
38
+ when :success, "success"
39
+ "<img src=\"#{IMG_STEP_OK}\" align=\"center\"/>"
40
+ when :error, "error"
41
+ "<img src=\"#{IMG_STEP_ERROR}\" align=\"center\"/>"
42
+ else
43
+ "<img src=\"#{IMG_STEP_WARN}\" align=\"center\"/>"
44
+ end
45
+ end
46
+ # Returns a string with the correct time format for display
47
+ def time_formatted time
48
+ time.strftime(TIME_FORMAT)
49
+ end
50
+ #Returns the URL of details page for a run
51
+ def run_url run
52
+ "/run/#{run.id}"
53
+ end
54
+
55
+ def run_summary r
56
+ #Ramaze::Log.debug("Summary snippet for #{r}") if @logger
57
+ msg="#{run_link(r)}"
58
+ if r.context.is_a?(Hash)
59
+ msg<<" started at #{time_formatted(r.context[:start_time])}"
60
+ end
61
+ return msg
62
+ end
63
+
64
+ def run_link r
65
+ "<a class=\"smallgreytext\" href=\"#{run_url(r)}\">Run #{r.id}</a>"
66
+ end
67
+ def cfg_link cfg
68
+ "<a class=\"smallgreytext\" href=\"/statistics/config_report/#{cfg}\">#{cfg}</a>"
69
+ end
70
+ #will render a hash in a table of key||value rows
71
+ def context_table context
72
+ ret=""
73
+ if context.is_a?(Hash)
74
+ ret="<p>"
75
+ ret<<"Run configured from #{context[:config_file]}<br/>" if context[:config_file]
76
+ ret<<"Started at #{time_formatted(context[:start_time])}<br/>"
77
+ ret<<"Ended at #{time_formatted(context[:end_time])}<br/>"
78
+ ret<<"Total duration #{context[:end_time]-context[:start_time]} seconds</p>"
79
+ end
80
+ return ret
81
+ end
82
+
83
+ #returns the pagination HTML for runs
84
+ def run_page_link page_number,page_total
85
+ ret=""
86
+ unless page_total==1
87
+ ret<<"<a href=\"/runs/#{page_number-1}\">Previous</a>" unless page_number==0
88
+ ret<<" | Page #{page_number+1}"
89
+ ret<<" | <a href=\"/runs/#{page_number+1}\">Next</a>" unless page_number==page_total-1
90
+ end
91
+ return ret
92
+ end
93
+ #returns the pagination HTML for scenarios
94
+ def scenario_page_link page_number,page_total
95
+ ret=""
96
+ unless page_total==1
97
+ ret<<"<a href=\"/scenarios/#{page_number-1}\">Previous</a>" unless page_number==0
98
+ ret<<" | Page #{page_number+1}"
99
+ ret<<" | <a href=\"/scenarios/#{page_number+1}\">Next</a>" unless page_number==page_total-1
100
+ end
101
+ return ret
102
+ end
103
+
104
+ #Gives the HTML to use for the status column of a scenario list
105
+ def scenario_status r
106
+ img_src=IMG_SCE_WARN
107
+ img_src=IMG_SCE_OK if "success"==r.status
108
+ img_src=IMG_SCE_ERROR if "error"==r.status
109
+ "<img src=\"#{img_src}\" align=\"center\"/>"
110
+ end
111
+
112
+ end
113
+
114
+ #Contains all the settings that control the display of information for RutemaWeb's controllers
115
+ module Settings
116
+ DEFAULT_PAGE_SIZE=10
117
+ @@rutemaweb_settings||=Hash.new
118
+ #Set to true to show all setup and teardown scenarios
119
+ def show_setup_teardown= v
120
+ @@rutemaweb_settings[:show_setup_teardown]= v
121
+ end
122
+
123
+ def show_setup_teardown?
124
+ return @@rutemaweb_settings[:show_setup_teardown]
125
+ end
126
+
127
+ def page_size= v
128
+ @@rutemaweb_settings[:page_size]=v
129
+ end
130
+
131
+ def page_size
132
+ @@rutemaweb_settings[:page_size]||=DEFAULT_PAGE_SIZE
133
+ return @@rutemaweb_settings[:page_size]
134
+ end
135
+ end
136
+
137
+ module Statistics
138
+ def self.gruff_working= v
139
+ @@gruff_working= v
140
+ end
141
+ def self.gruff_working?
142
+ return @@gruff_working
143
+ end
144
+ begin
145
+ require 'gruff'
146
+ self.gruff_working=true
147
+ rescue LoadError
148
+ self.gruff_working=false
149
+ end
150
+
151
+ private
152
+ #returns a jpg blob
153
+ def runs_graph_jpg successful,failed,labels
154
+ graph=Gruff::StackedBar.new(640)
155
+ graph.theme = {
156
+ :colors => %w(green red yellow blue),
157
+ :marker_color => 'black',
158
+ :background_colors => %w(white grey)
159
+ }
160
+ graph.x_axis_label="#{successful.size} runs"
161
+ graph.data("successful",successful)
162
+ graph.data("failed",failed)
163
+ graph.labels=labels
164
+ graph.marker_font_size=12
165
+ return graph.to_blob("PNG")
166
+ end
167
+ #extract all the configuration names
168
+ def configurations
169
+ runs=Rutema::Model::Run.find(:all)
170
+ return runs.map{|r| r.context[:config_file] if r.context.is_a?(Hash)}.compact.uniq
171
+ end
172
+ def panel_configurations
173
+ ret="<a href=\"/statistics/config_report\">all</a><br/>"
174
+ configurations.each do |cfg|
175
+ ret<<cfg_link(cfg)
176
+ ret<<"<br/>"
177
+ end
178
+ return ret
179
+ end
180
+ end
181
+
182
+ class SinatraApp<Sinatra::Base
183
+ include ViewUtilities
184
+ include Settings
185
+ include Statistics
186
+ enable :logging
187
+ enable :run
188
+ enable :static
189
+ set :server, %w[thin mongrel webrick]
190
+ set :port, 7000
191
+ set :root, File.dirname(__FILE__)
192
+ set :public, File.dirname(__FILE__) + '/public'
193
+
194
+ @@logger = Patir.setup_logger
195
+
196
+ get '/' do
197
+ @title="Rutema"
198
+ @panel_content=panel_runs
199
+ @content_title="Welcome to Rutema"
200
+ @content="<p>This is the rutema web interface.<br/>It allows you to browse the contents of the test results database.</p><p>Currently you can view the results for each separate run, the results for a specific scenario (a complete list of all steps executed in the scenario with standard and error output logs) or the complete execution history of a scenario.</p><p>The panel on the left shows a list of the ten most recent runs.</p>"
201
+ erb :layout
202
+ end
203
+
204
+ get '/runs/:page' do |page|
205
+ runs(page)
206
+ erb :layout
207
+ end
208
+ #Displays the details of a run
209
+ #
210
+ #Routes to /runs if no id is provided
211
+ get '/run/:run_id' do |run_id|
212
+ @panel_content=nil
213
+ if !run_id.empty?
214
+ @panel_content=panel_runs
215
+ @title="Run #{run_id}"
216
+ @content_title="Summary of run #{run_id}"
217
+ @content=single_run(run_id)
218
+ end
219
+ erb :layout
220
+ end
221
+
222
+ get '/run/?' do
223
+ runs(0)
224
+ erb :layout
225
+ end
226
+
227
+ get '/runs/?' do
228
+ runs(0)
229
+ erb :layout
230
+ end
231
+ #Displays a paginated list of scenarios
232
+ get '/scenarios/:page' do |page|
233
+ scenarios(page)
234
+ erb :layout
235
+ end
236
+ #Displays the details of a scenario
237
+ get '/scenario/:scenario_id' do |scenario_id|
238
+ @panel_content=""
239
+ if !scenario_id.empty?
240
+ if scenario_id.to_i==0
241
+ @content=scenario_by_name(scenario_id)
242
+ else
243
+ @content=scenario_in_a_run(scenario_id.to_i)
244
+ end
245
+ end
246
+ erb :layout
247
+ end
248
+
249
+ get '/scenario/?' do
250
+ scenarios(0)
251
+ erb :layout
252
+ end
253
+
254
+ get '/scenarios/?' do
255
+ scenarios(0)
256
+ erb :layout
257
+ end
258
+
259
+ get '/statistics/?' do
260
+ @title="Rutema"
261
+ @panel_content=panel_configurations
262
+ @content_title="Statistics"
263
+ @content="<p>rutema statistics provide reports that present the results on a time axis<br/>At present you can see the ratio of successful vs. failed test cases over time grouped per configuration file.</p>"
264
+ @content<<"statistics reports require the gruff gem which in turn depends on RMagick. gruff does not appear to be available!<br/>rutemaweb will not be able to produce statistics reports" unless Statistics.gruff_working?
265
+ erb :layout
266
+ end
267
+
268
+ get '/statistics/config_report/:configuration' do |configuration|
269
+ @title=configuration || "All configurations"
270
+ @panel_content=panel_configurations
271
+ @content_title= configuration || "All configurations"
272
+ if Statistics.gruff_working?
273
+ @content="<img src=\"/statistics/graph/#{configuration}\"/>"
274
+ else
275
+ @content="Could not generate graph.<p>This is probably due to a missing gruff/RMagick installation.</p><p>You will need to restart rutemaweb once the issue is resolved.</p>"
276
+ end
277
+ erb :layout
278
+ end
279
+
280
+ get '/statistics/graph/:configuration' do |configuration|
281
+ content_type "image/png"
282
+ successful=[]
283
+ failed=[]
284
+ labels=Hash.new
285
+ runs=Rutema::Model::Run.find(:all)
286
+ #find all runs beloging to this configuration
287
+ runs=runs.select{|r| r.context[:config_file]==configuration if r.context.is_a?(Hash)} if configuration
288
+ #now extract the data
289
+ counter=0
290
+ #the normalizer thins out the labels on the x axis so that they won't overlap
291
+ normalizer = 1
292
+ normalizer=runs.size/11 unless runs.size<=11
293
+ runs.each do |r|
294
+ fails=r.number_of_failed
295
+ #the scenarios array includes setup and teardown scripts as well - we want only the actual testcases
296
+ #so we use the added number_of_tests method that filters setup and test scripts
297
+ successful<<r.number_of_tests-fails
298
+ failed<<fails
299
+ #every Nth label
300
+ labels[counter]="R#{r.id}" if counter%normalizer==0
301
+ counter+=1
302
+ end
303
+ runs_graph_jpg(successful,failed,labels)
304
+ end
305
+ private
306
+ def runs page
307
+ @title="All runs"
308
+ @content_title="Runs"
309
+ @content=""
310
+ dt=[]
311
+ total_pages=(Rutema::Model::Run.count/page_size)+1
312
+ page_number=validated_page_number(page,total_pages)
313
+
314
+ runs=Rutema::Model::Run.find_on_page(page_number,page_size)
315
+ runs.each do |r|
316
+ dt<<[status_icon(r.status),run_summary(r),r.config_file]
317
+ end
318
+ @content<< Ruport::Data::Table.new(:data=>dt,:column_names=>["status","description","configuration"]).to_html
319
+ @content<<"<br/>"
320
+ @content<<run_page_link(page_number,total_pages)
321
+ end
322
+
323
+ def scenarios page
324
+ @title="All scenarios"
325
+ @content_title="Scenarios"
326
+ @content=""
327
+ @panel_content=panel_runs
328
+ runs=Hash.new
329
+ #find which runs contain each scenario with the same name
330
+ #Ramaze::Log.debug("Getting the runs for each scenario")
331
+ conditions="name NOT LIKE '%_teardown' AND name NOT LIKE '%_setup'"
332
+ Rutema::Model::Scenario.find(:all, :conditions=>conditions).each do |sc|
333
+ nm=sc.name
334
+ runs[nm]||=[]
335
+ runs[nm]<<sc.run.id
336
+ end
337
+ #the size of the hash is also the number of unique scenario names
338
+ total_pages=(runs.size / page_size)+1
339
+ page_number=validated_page_number(page,total_pages)
340
+ #Ramaze::Log.debug("Getting scenarios for page #{page_number}")
341
+ scens=Rutema::Model::Scenario.find_on_page(page_number,page_size,conditions)
342
+ #and now build the table data
343
+ dt=Array.new
344
+ scens.each do |sc|
345
+ nm=sc.name
346
+ #sort the run ids
347
+ runs[nm]=runs[nm].sort.reverse[0..4]
348
+ dt<<["<a href=\"/scenario/#{nm}\">#{nm}</a> : ",sc.title,runs[nm].map{|r| " <a href=\"/run/#{r}\">#{r}</a>"}.join(" "),"#{failure_rate(sc.name)}%"]
349
+ end
350
+ @content<<Ruport::Data::Table.new(:data=>dt,:column_names=>["name","title","last 5 runs","failure rate"]).to_html
351
+ @content<<"<br/>"
352
+ @content<<scenario_page_link(page_number,total_pages)
353
+ end
354
+ #Returns a valid page number no matter what __page__ is.
355
+ def validated_page_number page,total_pages
356
+ page_number=page.to_i if page
357
+ page_number||=0
358
+ #Ramaze::Log.debug("Total number of run pages is #{total_pages}")
359
+ if page_number<0 || page_number>total_pages-1
360
+ #Ramaze::Log.warn("Page number out of bounds: #{page_number}. Reseting")
361
+ page_number=0
362
+ end
363
+ return page_number
364
+ end
365
+
366
+ #Renders the summary of all runs for a single scenario
367
+ def scenario_by_name scenario_id
368
+ ret=""
369
+ @title="Runs for #{scenario_id}"
370
+ @content_title="Scenario #{scenario_id} runs"
371
+ begin
372
+ table=Rutema::Model::Scenario.report_table(:all,:conditions=>["name = :spec_name",{:spec_name=>scenario_id}],
373
+ :order=>"run_id DESC")
374
+ if table.empty?
375
+ ret="<p>no results for the given name</p>"
376
+ else
377
+ table.replace_column("status"){|r| scenario_status(r)}
378
+ table.replace_column("name") { |r| "<a href=\"/scenario/#{r}\">#{r}</a>"}
379
+ table.replace_column("start_time"){|r| r.stop_time ? r.start_time.strftime(TIME_FORMAT) : nil}
380
+ table.replace_column("stop_time"){|r| r.stop_time ? r.stop_time.strftime(TIME_FORMAT) : nil}
381
+ table.replace_column("run_id"){|r| "<a class=\"smallgreytext\" href=\"/run/#{r.run_id}\">Run #{r.run_id}</a>"}
382
+ table.reorder("status","run_id","title","start_time","stop_time")
383
+ table.column_names=["status","run","title","started at","ended at"]
384
+ ret<<table.to_html
385
+ end
386
+ rescue
387
+ @content_title="Error"
388
+ @title=@content_title
389
+ #Ramaze::Log.error("Could not retrieve data for the scenario name '#{scenario_id}'")
390
+ #Ramaze::Log.debug("#{$!.message}:\n#{$!.backtrace}")
391
+ ret="<p>could not retrieve data for the given scenario name</p>"
392
+ end
393
+ return ret
394
+ end
395
+ #Renders the information for a specific executed scenario
396
+ #giving a detailed list of the steps, with status and output
397
+ def scenario_in_a_run scenario_id
398
+ @panel_content=panel_runs
399
+ begin
400
+ scenario=Rutema::Model::Scenario.find(scenario_id)
401
+ @content_title="Summary for #{scenario.name} in run #{scenario.run_id}"
402
+ @title=@content_title
403
+ table=Rutema::Model::Step.report_table(:all,
404
+ :conditions=>["scenario_id = :scenario_id",{:scenario_id=>scenario_id}],
405
+ :order=>"number ASC")
406
+ if table.empty?
407
+ ret="<p>no results for the given id</p>"
408
+ else
409
+ table.replace_column("status"){|r| status_icon(r.status)}
410
+ ret=table.to_vhtml
411
+ end
412
+ rescue
413
+ @content_title="Error"
414
+ @title=@content_title
415
+ #Ramaze::Log.error("Could not find scenario with the id '#{scenario_id}'")
416
+ @@logger.warn("#{$!.message}:\n#{$!.backtrace}")
417
+ ret="<p>Could not find scenario with the given id.</p>"
418
+ end
419
+ return ret
420
+ end
421
+
422
+ #Renders the information for a single run providing the context and a list of the scenarios
423
+ def single_run run_id
424
+ ret=""
425
+ begin
426
+ run=Rutema::Model::Run.find(run_id)
427
+ rescue
428
+ return "Could not find #{run_id}"
429
+ end
430
+ if run.context
431
+ ret<<context_table(run.context)
432
+ end
433
+ conditions="run_id = :run_id AND name NOT LIKE '%_teardown' AND name NOT LIKE '%_setup'"
434
+ table=Rutema::Model::Scenario.report_table(:all,
435
+ :conditions=>[conditions,{:run_id=>run_id}],:except=>["run_id"],
436
+ :order=>"name ASC")
437
+ if table.empty?
438
+ ret<<"No scenarios for run #{run_id}"
439
+ else
440
+ table.replace_column("status") {|r| scenario_status(r) }
441
+ table.replace_column("name"){ |r| "<a href=\"/scenario/#{r.id}\">#{r.name}</a>" }
442
+ table.replace_column("start_time"){|r| r.start_time ? r.start_time.strftime(TIME_FORMAT) : nil}
443
+ table.replace_column("stop_time"){|r| r.stop_time ? r.stop_time.strftime(TIME_FORMAT) : nil}
444
+ table.reorder("status","name","title","start_time","stop_time")
445
+ table.column_names=["status","name","title","started at","ended at"]
446
+ ret<<table.to_html
447
+ end
448
+ return ret
449
+ end
450
+
451
+ def panel_runs
452
+ ret=""
453
+ Rutema::Model::Run.find(:all,:limit=>10,:order=>"id DESC").each do |r|
454
+ ret<<"#{status_icon(r.status)} #{run_link(r)}<br/>"
455
+ end
456
+ return ret
457
+ end
458
+
459
+ def failure_rate scenario_name
460
+ scenarios=Rutema::Model::Scenario.find(:all,:conditions=>["name = :spec_name",{:spec_name=>scenario_name}])
461
+ failures=0
462
+ scenarios.each{|sc| failures+=1 unless sc.status=="success" }
463
+ return ((failures.to_f/scenarios.size)*100).round
464
+ end
465
+ end#SinatraApp
466
+ end#UI module
467
+ end
@@ -0,0 +1,54 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta name="author" content="Vassilis Rizopoulos" />
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf8" />
6
+ <link rel="stylesheet" href="/css/style.css" type="text/css" />
7
+ <script src="/js/jquery.js"></script>
8
+ <script src="/js/folding.js"></script>
9
+ <script type="text/javascript">
10
+ $(document).ready(toggleFolding);
11
+ </script>
12
+ <title><%=@title%></title>
13
+ </head>
14
+ <body>
15
+ <div id="page" align="center">
16
+ <div id="content" style="width:800px">
17
+ <div id="logo">
18
+ <div style="margin-top:70px" class="whitetitle">rutema</div>
19
+ </div>
20
+ <div id="topheader">
21
+ <div align="left" class="bodytext">
22
+ </div>
23
+ <div id="toplinks" class="smallgraytext">
24
+ </div>
25
+ </div>
26
+ <div id="menu">
27
+ <div align="right" class="smallwhitetext" style="padding:9px;">
28
+ <a href="/">Home</a> | <a href="/run">Runs</a> | <a href="/scenario">Scenarios</a> | <a href="/statistics">Statistics</a>
29
+ </div>
30
+ </div>
31
+ <div id="submenu">
32
+ <div align="right" class="smallgraytext" style="padding:9px;"></div>
33
+ </div>
34
+ <div id="contenttext">
35
+ <div style="padding:10px">
36
+ <span class="titletext"><%=@content_title%></span>
37
+ </div>
38
+ <div class="bodytext" style="padding:12px;" align="justify"><%=@content%></div>
39
+ </div>
40
+ <div id="leftpanel">
41
+ <% if @panel_content && !@panel_content.empty? %>
42
+ <div align="justify" class="graypanel">
43
+ <%=@panel_content%>
44
+ </div>
45
+ <% end %>
46
+ </div>
47
+ <div id="footer" class="smallgraytext">
48
+ rutemaweb v<%= RutemaWeb::Version::STRING %> | <a href="/">Home</a> | <a href="http://patir.rubyforge.org/rutema">about rutema</a> |
49
+ &copy; 2008 - 2009 <a href="http://www.braveworld.net/riva" target="_blank">Vassilis Rizopoulos</a>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </body>
54
+ </html>
@@ -0,0 +1,48 @@
1
+ require 'test/unit'
2
+ require 'ostruct'
3
+ require 'rutema_web/ramaze_controller'
4
+ require 'rubygems'
5
+ require 'mocha'
6
+
7
+ class TestModel <Test::Unit::TestCase
8
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3",:database =>":memory:")
9
+ Rutema::Model::Schema.up
10
+ def setup
11
+ @stp=Rutema::Model::Scenario.new
12
+ @stp.name="test_setup"
13
+ @trd=Rutema::Model::Scenario.new
14
+ @trd.name="test_teardown"
15
+ @tst=Rutema::Model::Scenario.new
16
+ @tst.name="test"
17
+ @r=Rutema::Model::Run.new
18
+ @r.scenarios=[@stp,@tst,@trd]
19
+ end
20
+ def test_status
21
+ assert_equal(:success,@r.status)
22
+ t1=Rutema::Model::Scenario.new
23
+ t1.name="failed"
24
+ t1.stubs(:status).returns("error")
25
+ @r.scenarios<<t1
26
+ assert_equal(:error,@r.status)
27
+ end
28
+ def test_is_test?
29
+ assert(!@stp.is_test?, "Setup as test")
30
+ assert(!@trd.is_test?, "Teardown as test")
31
+ assert(@tst.is_test?, "Test not a test")
32
+ end
33
+ def test_number_of_tests
34
+ assert_equal(1, @r.number_of_tests)
35
+ end
36
+ def test_number_of_failed
37
+ t1=Rutema::Model::Scenario.new
38
+ t1.name="failed"
39
+ t1.stubs(:status).returns("error")
40
+ t2=Rutema::Model::Scenario.new
41
+ t2.name="not executed"
42
+ t2.stubs(:status).returns("not_executed")
43
+ @tst.stubs(:status).returns("success")
44
+ @r.scenarios<<t1
45
+ @r.scenarios<<t2
46
+ assert_equal(2,@r.number_of_failed)
47
+ end
48
+ end