Project

General

Profile

Feature #1206 ยป ruby-changes.patch

Test::Unit::UI::Xml::TestRunner patch - flavio (Flavio Castelli), 02/25/2009 05:09 PM

View differences:

lib/test/unit/autorunner.rb (working copy)
41 41
          require 'test/unit/ui/tk/testrunner'
42 42
          Test::Unit::UI::Tk::TestRunner
43 43
        end,
44
        :xml => proc do |r|
45
          require 'test/unit/ui/xml/testrunner'
46
          Test::Unit::UI::Xml::TestRunner
47
        end,
48
        
44 49
      }
45 50

  
46 51
      OUTPUT_LEVELS = [
lib/test/unit/ui/xml/xml_report.dtd (revision 0)
1
<!ELEMENT unit_test (failures,errors)>
2

  
3
<!ATTLIST unit_test failures CDATA #REQUIRED
4
                     tests CDATA #REQUIRED
5
                     errors CDATA #REQUIRED
6
                     assertions CDATA #REQUIRED
7
                     elapsed_time CDATA #REQUIRED>
8

  
9
<!ELEMENT failures (failure*)>
10
<!ELEMENT failure (message,method,class,location)>
11

  
12
<!ELEMENT errors (error*)>
13
<!ELEMENT error (exception,method,class)>
14

  
15
<!ELEMENT exception (#PCDATA)>
16
<!ELEMENT message (#PCDATA)>
17
<!ELEMENT method (#PCDATA)>
18
<!ELEMENT class (#PCDATA)>
19
<!ELEMENT location (#PCDATA)>
20

  
lib/test/unit/ui/xml/testrunner.rb (revision 0)
1
#--
2
#
3
# Author:: Flavio Castelli.
4
# Copyright:: Copyright (c) 2009 Flavio Castelli. All rights reserved.
5
# License:: Ruby license.
6

  
7
require 'test/unit/ui/testrunnermediator'
8
require 'test/unit/ui/testrunnerutilities'
9
require 'test/unit/ui/console/testrunner'
10

  
11
require 'rexml/document'
12

  
13
include REXML
14

  
15
class Test::Unit::TestResult
16
  attr_reader :failures, :errors
17
end
18

  
19
module Test
20
  module Unit
21
    module UI
22
      module Xml
23

  
24
        # Behaves like Test::Unit::UI::Console::TestRunner but can create an xml
25
        # file containing the unit test results.
26
        # The xml file name is defined using an environment variable called _XML_OUTPUT_FILE_
27
        #
28
        # The output xml can be validated using the following DTD:
29
        #   <!ELEMENT unit_test (failures,errors)>
30
        # 
31
        #   <!ATTLIST unit_test failures CDATA #REQUIRED
32
        #                      tests CDATA #REQUIRED
33
        #                      errors CDATA #REQUIRED
34
        #                      assertions CDATA #REQUIRED
35
        #                      elapsed_time CDATA #REQUIRED>
36
        # 
37
        #   <!ELEMENT failures (failure*)>
38
        #   <!ELEMENT failure (message,method,class,location)>
39
        # 
40
        #   <!ELEMENT errors (error*)>
41
        #   <!ELEMENT error (exception,method,class)>
42
        # 
43
        #   <!ELEMENT exception (#PCDATA)>
44
        #   <!ELEMENT message (#PCDATA)>
45
        #   <!ELEMENT method (#PCDATA)>
46
        #   <!ELEMENT class (#PCDATA)>
47
        #   <!ELEMENT location (#PCDATA)>
48
        
49
        class TestRunner < Test::Unit::UI::Console::TestRunner
50
          
51
            # Creates a new TestRunner for running the passed
52
            # suite. If quiet_mode is true, the output while
53
            # running is limited to progress dots, errors and
54
            # failures, and the final result. io specifies
55
            # where runner output should go to; defaults to
56
            # STDOUT.
57
            def initialize(suite, output_level=NORMAL, io=STDOUT)
58
              super(suite, output_level, io)
59
            end
60
          
61
            def finished(elapsed_time)
62
              super(elapsed_time)
63
              
64
              xml_file_path = ENV["XML_OUTPUT_FILE"]
65

  
66
              if xml_file_path.nil?
67
                nl
68
                output("Provide XML_OUTPUT_FILE environment variable in order to save unit test result to file")
69
                nl
70
              else
71
                nl
72
                File.open(xml_file_path,'w') {|file| file.write(generate_xml(elapsed_time)) }
73
                output("Xml summary saved: #{xml_file_path}")
74
                nl
75
              end
76
            end
77

  
78
            private
79
            
80
            # Generates the xml file containing the unit test stats
81
            def generate_xml(elapsed_time)
82
              xml = Document.new
83
              unit_test = Element.new "unit_test"
84
              unit_test.add_attributes( {"tests" => @result.run_count.to_s,
85
                                  "assertions" => @result.assertion_count.to_s,
86
                                  "failures" => @result.failures.size.to_s,
87
                                  "errors" => @result.errors.size.to_s,
88
                                  "elapsed_time" => elapsed_time.to_s})
89
              xml.elements << unit_test
90
              
91
              failures = Element.new("failures")
92
              @result.failures.each do |failure|
93
                failure_element = Element.new("failure")
94
              
95
                message = failure_element.add_element("message")
96
                message.text = failure.message
97
              
98
                method_name = failure_element.add_element "method"
99
                class_name = failure_element.add_element "class"
100
              
101
                failure.test_name =~ /(\w+\_\w+)\((.+)\)/
102
                method_name.text = $1
103
                class_name.text = $2
104
              
105
                location = failure_element.add_element("location")
106
                location.text = failure.location
107
              
108
                failures.elements << failure_element
109
              end
110
              unit_test.elements << failures
111
              
112
              errors = Element.new("errors")
113
              @result.errors.each do |error|
114
                error_element = Element.new("error")
115
              
116
                exception = error_element.add_element("exception")
117
                exception.text = error.exception
118
              
119
                method_name = error_element.add_element "method"
120
                class_name = error_element.add_element "class"
121
              
122
                error.test_name =~ /(\w+\_\w+)\((.+)\)/
123
                method_name.text = $1
124
                class_name.text = $2
125
              
126
                errors.elements << error_element
127
              end
128
              unit_test.elements << errors
129
              
130
              xml
131
            end
132

  
133
        end
134
      end
135
    end
136
  end
137
end
138

  
139
if __FILE__ == $0
140
  Test::Unit::UI::Xml::TestRunner.start_command_line_test
141
end