Class: Test4requirements::RequirementList

Inherits:
Object
  • Object
show all
Defined in:
lib/test4requirements/requirementlist.rb

Overview

Define a list of requirements.

This class can be used in Test::Unit::TestCase#assign_requirement.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, *args) ⇒ RequirementList

Define a list of requirements.

Parameters:

  • name

  • list of requirement (keys)

  • options

    • :requirements

    • :log Define a logger

The list of requirements will define the key of a new Test4requirements::Requirement, unless it is already a Test4requirements::Requirement.

Examples:

RequirementList.new('Request_4711')
RequirementList.new('Request_4711', :req1, :req2 )
RequirementList.new('Request_4711', Reqirement.new(:req1), Reqirement.new(:req2) )
RequirementList.new('Request_4711', 
    :requirements => [ :req1, :req2]
  )
RequirementList.new('Request_4711', 
    Reqirement.new(:req1), Reqirement.new(:req2),
    :requirements => [ :req3, :req4]
  )


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/test4requirements/requirementlist.rb', line 41

def initialize( name, *args )
  
  options = {
    :log => Log4r::Logger.new('ReqL'),
    :requirements => [],
    }.merge( args.last.is_a?(Hash) ? args.pop : {} )
  options[:requirements].concat(args)
  
  @name = name
  @log = options[:log]
  
  @requirements = {}
  options[:requirements].each{|req|
  
    #Define a requirement.
    if ! req.is_a?(Requirement)
      req = Requirement.new(req)
    end

    self << req
  }
  @testsresults = []

  #Yes, we need two at_exit.
  #tests are done also at_exit.  With double at_exit, we are after that.
  #Maybe better to be added later.
  at_exit {
    at_exit do 
      self.overview
    end 
  }
  @report_type = self.class.report_type_default # alternatives: nil, :stdout, :txt
end

Class Attribute Details

.report_type_defaultObject

alternatives: nil, :stdout, :txt fixme: check valid values. see #report_type=



11
12
13
# File 'lib/test4requirements/requirementlist.rb', line 11

def report_type_default
  @report_type_default
end

Instance Attribute Details

#logObject (readonly)

Logger



77
78
79
# File 'lib/test4requirements/requirementlist.rb', line 77

def log
  @log
end

#nameObject (readonly)

Name or ID of the requirement list.



75
76
77
# File 'lib/test4requirements/requirementlist.rb', line 75

def name
  @name
end

#testsresultsObject (readonly)

List of related result objects Test::Unit::TestResult (one per suite, normally only 1)



79
80
81
# File 'lib/test4requirements/requirementlist.rb', line 79

def testsresults
  @testsresults
end

Instance Method Details

#<<(req) ⇒ Object

Add a new requirement.

Raises:

  • (ArgumentError)


84
85
86
87
88
89
90
91
92
# File 'lib/test4requirements/requirementlist.rb', line 84

def <<(req)
  raise ArgumentError, "Requirement is no Requiremnt but #{req.inspect}" unless req.is_a?(Requirement)
  @log.info("Add requirement #{req.key}") if @log.info?
  if @requirements[req.key]
    raise ArgumentError, "Requirement #{req.key} defined twice"
  end
  req.log= Log4r::Logger.new("#{@log.name}::#{req.key}") unless req.log
  @requirements[req.key] = req
end

#[](key) ⇒ Object

Returns Requirement



130
131
132
# File 'lib/test4requirements/requirementlist.rb', line 130

def [](key)
  @requirements[key]
end

#analyse_testresultsObject



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/test4requirements/requirementlist.rb', line 172

def analyse_testresults()
  @testsresults.each{|result|
    result.faults.each{|fault|
      self.each{|req|
        if ! req[fault.test_name].nil?
          @log.debug("Set result #{fault} to #{req}") if @log.info?
          case fault
            when Test::Unit::Failure; req.result(fault.test_name, :failure)
            when Test::Unit::Pending; req.result(fault.test_name, :pend)
            when Test::Unit::Omission; req.result(fault.test_name, :omit)
            else 
              @log.error("unknown fault-type #{fault.inspect}") if @log.error?
              req.set_result(fault.test_name, :error)
          end
        end
      }
      
    }
  }
end

#assign_test(req, testcase, result) ⇒ Object

Assign a testcase to an requirement.

Requires:

  • Requirement key

  • testcase (Class#methodname)

Raises:

  • (ArgumentError)


149
150
151
152
153
154
155
# File 'lib/test4requirements/requirementlist.rb', line 149

def assign_test(req, testcase, result)
  raise ArgumentError unless @requirements[req]
  #~ raise ArgumentError, "result is no Test::Unit::TestResult but #{result.inspect}" unless result.is_a?(Test::Unit::TestResult)
  @requirements[req].test= testcase
  #Assign the related result object Test::Unit::TestResult
  @testsresults << result unless @testsresults.include?(result)
end

#do_after_testsObject

Define an action at the end of the script (after the test).

This method can be used for user defined actions after test execution.

Raises:

  • (ArgumentError)


243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/test4requirements/requirementlist.rb', line 243

def do_after_tests
  raise ArgumentError, "do_after_tests: called without a block" unless block_given?
  #Yes, we need two at_exit.
  #The inner at_exit defines the action,
  #the outer at_exit defines the action at the end. 
  #So it will be after the at_exit used by unit-test runner.
  at_exit{
    at_exit{
      yield self
    }
  }
end

#eachObject

Loop on all requirements.

Returns list of all requirements.



138
139
140
141
# File 'lib/test4requirements/requirementlist.rb', line 138

def each()
  @requirements.each{|key,req| yield req} if block_given?
  @requirements.values
end

#load(data) ⇒ Object

Method to load requirements.

You can provide:

  • an array of hashes with requirement definition

  • a hash with key and requirement definition

The requirement definition can contain the options of Test4requirements::Requirement.

You may use yaml to define your requirments:

req = RequirementList.new('Requirementlist')
req.load( YAML.load( <<yaml
      req1:
        description: 'What is required',
        reference: 'Customer Requirement, Version 2011-08-02, page 12'
      req2:
        description: 'What is required',
        reference: 'Customer Requirement, Version 2011-08-02, page 13'
    yaml
  ))


114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/test4requirements/requirementlist.rb', line 114

def load( data )
  
  if data.is_a?(Hash)
    #build array
    datalist = []
    data.each{|key,value| datalist  << value.merge(:key => key )} 
  else
    datalist = data
  end
  datalist.each{|req|
    self << Requirement.new( req[:key], req )
  }
end

#overview(report_type = @report_type) ⇒ Object

Give an overview.

Returns a hash with test results for the requirements.

  • true: Successfull tested

  • false: Unsuccessfull tested

  • nil: Not tested

The parameter defines alternative report types:

  • nil: No output. Please evaluate the return value

  • stdout: Result is written to stdout.

  • :txt: The text of stdout as an Array



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/test4requirements/requirementlist.rb', line 205

def overview(report_type = @report_type )
  
  analyse_testresults()
  
  txt = []
  hash = {}
  
  @requirements.each{|key, req|
    if req.successfull?
      txt << "Requirement #{key} was successfull tested (#{req.testresults.join(', ')})"
      hash[key] = true
    elsif req.test_defined?
      txt << "Requirement #{key} was unsuccessfull tested (#{req.testresults.join(', ')})"
      hash[key] = false
    else
      txt << "Requirement #{key} was not tested"
      hash[key] = nil
    end
  }

  case report_type
    when :stdout
      puts "Requirements overview:"
      puts txt.join("\n")
    when :txt
      return txt
    when nil 
      return hash
    else
      raise ArgumentError, "Undefined report type #{report_type}"
    end
  
end

#report_type=(key) ⇒ Object

Defines, how and if an overview of the requirements are given.

Used in #overview. More details see there.



161
162
163
164
165
166
167
168
169
# File 'lib/test4requirements/requirementlist.rb', line 161

def report_type=(key)
  @log.info("Set report type #{key.inspect}") if @log.info?
  case key 
    when :stdout, nil, :txt
      @report_type = key
    else
      raise ArgumentError, "Unknown report type #{key} for #{self.class}"
  end
end