rutema 0.1

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,170 @@
1
+ # Copyright (c) 2007 Vassilis Rizopoulos. All rights reserved.
2
+ require 'rubygems'
3
+ require 'patir/command'
4
+
5
+ module Rutema
6
+ #This module adds functionality that allows us to
7
+ #arbitrarily add attributes to a class and then have
8
+ #the accessor methods for these attributes appear automagically.
9
+ #
10
+ #It will also add a has_attribute? method to query if an attribute is part of the object or not.
11
+ module SpecificationElement
12
+ #adds an attribute to the class with the given __value__. __symbol__ can be a Symbol or a String, the rest are silently ignored
13
+ def attribute symbol,value
14
+ @attributes||=Hash.new
15
+ case symbol
16
+ when String : @attributes[:"#{symbol}"]=value
17
+ when Symbol : @attributes[symbol]=value
18
+ end
19
+ end
20
+ #allows us to call object.attribute, object.attribute=, object.attribute? and object.has_attribute?
21
+ #
22
+ #object.attribute and object.attribute? will throw NoMethodError if no attribute is set.
23
+ #
24
+ #object.attribute= will set the attribute to the right operand and
25
+ #object.has_attribute? returns false or true according to the existence of the attribute.
26
+ def method_missing symbol,*args
27
+ @attributes||=Hash.new
28
+ key=symbol.id2name.chomp('?').chomp('=').sub(/^has_/,"")
29
+ @attributes[:"#{key}"]=args[0] if key+"="==symbol.id2name
30
+ if @attributes.has_key?(:"#{key}")
31
+ return true if "has_"+key+"?"==symbol.id2name
32
+ return @attributes[:"#{key}"]
33
+ else
34
+ return false if "has_"+key+"?"==symbol.id2name
35
+ super(symbol,*args)
36
+ end
37
+ end
38
+ end
39
+
40
+
41
+ #A TestSpecification encompasses all elements required to run a test, the builds used, the scenario to run,
42
+ #together with a textual description and information that aids in tracing the test back to the requirements.
43
+ class TestSpecification
44
+ include SpecificationElement
45
+ attr_accessor :scenario,:requirements
46
+ #Following keys have meaning in initialization:
47
+ #
48
+ #:name - the name of the testcase. Should uniquely identify the testcase
49
+ #
50
+ #:title - a one liner describing what the testcase does
51
+ #
52
+ #:filename - the filename describing the testcase
53
+ #
54
+ #:description - a full textual description for the testcase. To be used in reports and documents
55
+ #
56
+ #:scenario - An instance of TestScenario
57
+ #
58
+ #:requirements - An Array of String. The idea is that the strings can lead you back to the requirements specification that is tested here.
59
+ #
60
+ #Default values are empty strings and arrays. (scenario is nil)
61
+ def initialize *args
62
+ params=args[0] if args
63
+ begin
64
+ @attributes=params
65
+ end if params
66
+ @attributes||=Hash.new
67
+ @attributes[:name]||=""
68
+ @attributes[:title]||=""
69
+ @attributes[:filename]||=""
70
+ @attributes[:description]||=""
71
+ @scenario=TestScenario.new
72
+ @requirements||=Array.new
73
+ end
74
+ end
75
+
76
+ #A TestScenario is a sequence of TestStep instances.
77
+ #
78
+ #TestStep instances are run in the definition sequence and the scenario
79
+ #is succesfull when all steps are succesfull.
80
+ #
81
+ #From the execution point of view each step is either succesfull or failed and it depends on
82
+ #the exit code of the step's command.
83
+ #
84
+ #Failure in a step results in the interruption of execution and the report of the errors.
85
+ class TestScenario
86
+ include SpecificationElement
87
+ attr_reader :steps
88
+
89
+ def initialize
90
+ @attended=false
91
+ @steps=Array.new
92
+ end
93
+
94
+ def attended?
95
+ return @attended
96
+ end
97
+
98
+ def add_step step
99
+ @steps<<step
100
+ @attended=true if step.attended?
101
+ end
102
+
103
+ def steps= array_of_steps
104
+ @steps=array_of_steps
105
+ @steps.each do |step|
106
+ @attended=true if step.attended?
107
+ end
108
+ end
109
+ end
110
+
111
+ #Represents a step in a TestScenario.
112
+ #
113
+ #Each TestStep can have text and a command associated with it.
114
+ #
115
+ #TestStep standard attributes are.
116
+ #
117
+ #attended - the step can only run in attended mode, it requires user input.
118
+ #
119
+ #step_type - a string identifying the type of the step. It is "step" by default.
120
+ #
121
+ #ignore - set to true if the step's success or failure is to be ignored. It essentially means that the step is always considered succesfull
122
+ #
123
+ #number - this is set when the step is assigned to a Scenario and is the sequence number
124
+ #
125
+ #cmd - the command associated with this step. This should quack like Patir::Command.
126
+ #
127
+ #status - one of :not_executed, :success, :warning, :error. Encapsulates the underlying command's status
128
+ class TestStep
129
+ include SpecificationElement
130
+ include Patir::Command
131
+
132
+ #_txt_ describes the step, _cmd_ is the command to run
133
+ def initialize txt="",cmd=nil
134
+ @attributes=Hash.new
135
+ #ignore is off by default
136
+ @attributes[:ignore]=false
137
+ #attended is off by default
138
+ @attributes[:attended]=false
139
+ #assign
140
+ @attributes[:cmd]=cmd if cmd
141
+ @attributes[:text]=txt
142
+ @attributes[:number]=0
143
+ end
144
+
145
+ def output
146
+ return "" unless @attributes[:cmd]
147
+ return @attributes[:cmd].output
148
+ end
149
+ def error
150
+ return "no command associated" unless @attributes[:cmd]
151
+ return @attributes[:cmd].error
152
+ end
153
+ def exec_time
154
+ return 0 unless @attributes[:cmd]
155
+ return @attributes[:cmd].exec_time
156
+ end
157
+ def status
158
+ return :warning unless @attributes[:cmd]
159
+ return @attributes[:cmd].status
160
+ end
161
+ def run
162
+ return not_executed unless @attributes[:cmd]
163
+ return @attributes[:cmd].run
164
+ end
165
+ def reset
166
+ @attributes[:cmd].reset if @attributes[:cmd]
167
+ end
168
+ end
169
+
170
+ end