rutema_web 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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