mirror of
https://github.com/ThrowTheSwitch/Unity.git
synced 2026-01-23 00:15:58 +01:00
219 lines
6.8 KiB
Ruby
219 lines
6.8 KiB
Ruby
#============================================================
|
|
# Author: John Theofanopoulos
|
|
# A simple parser. Takes the output files generated during the build process and
|
|
# extracts information relating to the tests.
|
|
#
|
|
# Notes:
|
|
# To capture an output file under VS builds use the following:
|
|
# devenv [build instructions] > Output.txt & type Output.txt
|
|
#
|
|
# To capture an output file under GCC/Linux builds use the following:
|
|
# make | tee Output.txt
|
|
#
|
|
# To use this parser use the following command
|
|
# ruby parseOutput.rb [options] [file]
|
|
# options: -xml : produce a JUnit compatible XML file
|
|
# file : file to scan for results
|
|
#============================================================
|
|
|
|
class ParseOutput
|
|
# The following flag is set to true when a test is found or false otherwise.
|
|
@testFlag
|
|
@xmlOut
|
|
@arrayList
|
|
@totalTests
|
|
@classIndex
|
|
|
|
# Set the flag to indicate if there will be an XML output file or not
|
|
def setXmlOutput
|
|
@xmlOut = true
|
|
end
|
|
|
|
# if write our output to XML
|
|
def writeXmlOuput
|
|
output = File.open('report.xml', 'w')
|
|
output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
|
@arrayList.each do |item|
|
|
output << item << "\n"
|
|
end
|
|
output << "</testsuite>\n"
|
|
end
|
|
|
|
# This function will try and determine when the suite is changed. This is
|
|
# is the name that gets added to the classname parameter.
|
|
def testSuiteVerify(testSuiteName)
|
|
if @testFlag == false
|
|
@testFlag = true
|
|
# Split the path name
|
|
testName = testSuiteName.split('/')
|
|
# Remove the extension
|
|
baseName = testName[testName.size - 1].split('.')
|
|
@testSuite = 'test.' + baseName[0]
|
|
printf "New Test: %s\n", @testSuite
|
|
end
|
|
end
|
|
|
|
# Test was flagged as having passed so format the output
|
|
def testPassed(array)
|
|
lastItem = array.length - 1
|
|
testName = array[lastItem - 1]
|
|
testSuiteVerify(array[@className])
|
|
printf "%-40s PASS\n", testName
|
|
if @xmlOut == true
|
|
@arrayList.push ' <testcase classname="' + @testSuite + '" name="' + testName + '"/>'
|
|
end
|
|
end
|
|
|
|
# Test was flagged as having passed so format the output.
|
|
# This is using the Unity fixture output and not the original Unity output.
|
|
def testPassedUnityFixture(array)
|
|
testSuite = array[0].sub('TEST(', '')
|
|
testSuite = testSuite.sub(',', '')
|
|
testName = array[1].sub(')', '')
|
|
if @xmlOut == true
|
|
@arrayList.push ' <testcase classname="' + testSuite + '" name="' + testName + '"/>'
|
|
end
|
|
end
|
|
|
|
# Test was flagged as being ingored so format the output
|
|
def testIgnored(array)
|
|
lastItem = array.length - 1
|
|
testName = array[lastItem - 2]
|
|
reason = array[lastItem].chomp
|
|
testSuiteVerify(array[@className])
|
|
printf "%-40s IGNORED\n", testName
|
|
|
|
if testName.start_with? 'TEST('
|
|
array2 = testName.split(' ')
|
|
@testSuite = array2[0].sub('TEST(', '')
|
|
@testSuite = @testSuite.sub(',', '')
|
|
testName = array2[1].sub(')', '')
|
|
end
|
|
|
|
if @xmlOut == true
|
|
@arrayList.push ' <testcase classname="' + @testSuite + '" name="' + testName + '">'
|
|
@arrayList.push ' <skipped type="TEST IGNORED"> ' + reason + ' </skipped>'
|
|
@arrayList.push ' </testcase>'
|
|
end
|
|
end
|
|
|
|
# Test was flagged as having failed so format the line
|
|
def testFailed(array)
|
|
lastItem = array.length - 1
|
|
testName = array[lastItem - 2]
|
|
reason = array[lastItem].chomp + ' at line: ' + array[lastItem - 3]
|
|
testSuiteVerify(array[@className])
|
|
printf "%-40s FAILED\n", testName
|
|
|
|
if testName.start_with? 'TEST('
|
|
array2 = testName.split(' ')
|
|
@testSuite = array2[0].sub('TEST(', '')
|
|
@testSuite = @testSuite.sub(',', '')
|
|
testName = array2[1].sub(')', '')
|
|
end
|
|
|
|
if @xmlOut == true
|
|
@arrayList.push ' <testcase classname="' + @testSuite + '" name="' + testName + '">'
|
|
@arrayList.push ' <failure type="ASSERT FAILED"> ' + reason + ' </failure>'
|
|
@arrayList.push ' </testcase>'
|
|
end
|
|
end
|
|
|
|
# Figure out what OS we are running on. For now we are assuming if it's not Windows it must
|
|
# be Unix based.
|
|
def detectOS
|
|
myOS = RUBY_PLATFORM.split('-')
|
|
@className = if myOS.size == 2
|
|
if myOS[1] == 'mingw32'
|
|
1
|
|
else
|
|
0
|
|
end
|
|
else
|
|
0
|
|
end
|
|
end
|
|
|
|
# Main function used to parse the file that was captured.
|
|
def process(name)
|
|
@testFlag = false
|
|
@arrayList = []
|
|
|
|
detectOS
|
|
|
|
puts 'Parsing file: ' + name
|
|
|
|
testPass = 0
|
|
testFail = 0
|
|
testIgnore = 0
|
|
puts ''
|
|
puts '=================== RESULTS ====================='
|
|
puts ''
|
|
File.open(name).each do |line|
|
|
# Typical test lines look like this:
|
|
# <path>/<test_file>.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0
|
|
# <path>/<test_file>.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented
|
|
# <path>/<test_file>.c:115:test_tc5100_initCanVoidPtrs:PASS
|
|
#
|
|
# where path is different on Unix vs Windows devices (Windows leads with a drive letter)
|
|
lineArray = line.split(':')
|
|
lineSize = lineArray.size
|
|
# If we were able to split the line then we can look to see if any of our target words
|
|
# were found. Case is important.
|
|
if (lineSize >= 4) || (line.start_with? 'TEST(')
|
|
# Determine if this test passed
|
|
if line.include? ':PASS'
|
|
testPassed(lineArray)
|
|
testPass += 1
|
|
elsif line.include? ':FAIL:'
|
|
testFailed(lineArray)
|
|
testFail += 1
|
|
elsif line.include? ':IGNORE:'
|
|
testIgnored(lineArray)
|
|
testIgnore += 1
|
|
elsif line.start_with? 'TEST('
|
|
if line.include? ' PASS'
|
|
lineArray = line.split(' ')
|
|
testPassedUnityFixture(lineArray)
|
|
testPass += 1
|
|
end
|
|
# If none of the keywords are found there are no more tests for this suite so clear
|
|
# the test flag
|
|
else
|
|
@testFlag = false
|
|
end
|
|
else
|
|
@testFlag = false
|
|
end
|
|
end
|
|
puts ''
|
|
puts '=================== SUMMARY ====================='
|
|
puts ''
|
|
puts 'Tests Passed : ' + testPass.to_s
|
|
puts 'Tests Failed : ' + testFail.to_s
|
|
puts 'Tests Ignored : ' + testIgnore.to_s
|
|
@totalTests = testPass + testFail + testIgnore
|
|
if @xmlOut == true
|
|
heading = '<testsuite tests="' + @totalTests.to_s + '" failures="' + testFail.to_s + '"' + ' skips="' + testIgnore.to_s + '">'
|
|
@arrayList.insert(0, heading)
|
|
writeXmlOuput
|
|
end
|
|
|
|
# return result
|
|
end
|
|
end
|
|
|
|
# If the command line has no values in, used a default value of Output.txt
|
|
parseMyFile = ParseOutput.new
|
|
|
|
if ARGV.size >= 1
|
|
ARGV.each do |a|
|
|
if a == '-xml'
|
|
parseMyFile.setXmlOutput
|
|
else
|
|
parseMyFile.process(a)
|
|
break
|
|
end
|
|
end
|
|
end
|