chpod
06-11-2008 20:25:29
Hi all,
There are often broken demos... This is natural, there are so many features to test and, as far as I know no autotest feature is available... yet. Today I tried to implement such a feature on the demos. This would help to check if everything is ok, right upon package compilation, or in order to test a new hardware platform, or different openGL/DirectX settings...
My idea is to add switches to the demos, so that they automatically take screenshots that can later be compared to reference screenshots.
I implemented my first tests on Demo_Bezier.py.
In order to take reference screenshots, i introduced the --reference switch:
And then, at any time, you may run the same demo with the --runtests switch:
Finally, autotest.py makes a comprehensive report of the difference between files.
autotest.py also produces a HTML summary (in this case I moved the mouse just before the last screenshot in order to produce a non matching picture):

Regarding modifications to Demo_Bezier, they just consist in adding one OnFrameEnded method, and modifying __init__ for class BezierListener:
Complete source files can be downloaded here:
http://chpod.free.fr/screenshots/20081106_Demo_Bezier.py
http://chpod.free.fr/screenshots/20081106_autotest.py
This a just a first and basic try. It shows that autotesting can be implemented quite easily, without the need to rewrite the demos from scratch.
Right now, I am trying to get rid of the "Rendering subsystem" window. I would like to be able to control those settings from the command line. Does anyone know how to do this?
Any input greatly appreciated,
Thanks,
chpod
There are often broken demos... This is natural, there are so many features to test and, as far as I know no autotest feature is available... yet. Today I tried to implement such a feature on the demos. This would help to check if everything is ok, right upon package compilation, or in order to test a new hardware platform, or different openGL/DirectX settings...
My idea is to add switches to the demos, so that they automatically take screenshots that can later be compared to reference screenshots.
I implemented my first tests on Demo_Bezier.py.
In order to take reference screenshots, i introduced the --reference switch:
C:\PythonOgre_1.6RC1\demos\ogre>demo_bezier.py --reference
NEW_REFERENCE: ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.000000.PNG
NEW_REFERENCE: ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.200000.PNG
NEW_REFERENCE: ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.400000.PNG
NEW_REFERENCE: ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.600000.PNG
NEW_REFERENCE: ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.800000.PNG
NEW_REFERENCE: ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=1.000000.PNG
Screenshots dumped
And then, at any time, you may run the same demo with the --runtests switch:
SCREENSHOT: ./Screenshots/SCREENSHOT_Demo_Bezier_FACTOR=0.000000.PNG
SCREENSHOT: ./Screenshots/SCREENSHOT_Demo_Bezier_FACTOR=0.200000.PNG
SCREENSHOT: ./Screenshots/SCREENSHOT_Demo_Bezier_FACTOR=0.400000.PNG
SCREENSHOT: ./Screenshots/SCREENSHOT_Demo_Bezier_FACTOR=0.600000.PNG
SCREENSHOT: ./Screenshots/SCREENSHOT_Demo_Bezier_FACTOR=0.800000.PNG
SCREENSHOT: ./Screenshots/SCREENSHOT_Demo_Bezier_FACTOR=1.000000.PNG
Screenshots dumped
Finally, autotest.py makes a comprehensive report of the difference between files.
C:\PythonOgre_1.6RC1\demos\ogre>autotest.py
Images match: ./ScreenShots/SCREENSHOT_Demo_Bezier_FACTOR=0.000000.PNG ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.000000.PNG
Images match: ./ScreenShots/SCREENSHOT_Demo_Bezier_FACTOR=0.200000.PNG ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.200000.PNG
Images match: ./ScreenShots/SCREENSHOT_Demo_Bezier_FACTOR=0.400000.PNG ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.400000.PNG
Images match: ./ScreenShots/SCREENSHOT_Demo_Bezier_FACTOR=0.600000.PNG ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.600000.PNG
Images match: ./ScreenShots/SCREENSHOT_Demo_Bezier_FACTOR=0.800000.PNG ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=0.800000.PNG
!! Images differ: ./ScreenShots/SCREENSHOT_Demo_Bezier_FACTOR=1.000000.PNG ./ReferenceScreenShots/REFERENCE_Demo_Bezier_FACTOR=1.000000.PNG
!! Images differ: at position 78x399 pixel value: (39, 36, 34)
autotest.py also produces a HTML summary (in this case I moved the mouse just before the last screenshot in order to produce a non matching picture):
Regarding modifications to Demo_Bezier, they just consist in adding one OnFrameEnded method, and modifying __init__ for class BezierListener:
def __init__(self, renderWindow, camera ):
self.timeLapse = 0.0
self.factor = 0.0
self.wireframe = 0
self.renderWindow = renderWindow
sf.FrameListener.__init__(self, renderWindow, camera)
# Are we in test mode?
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-t", "--runtests" , dest="test" ,action="store_true",default=False)
parser.add_option("-r", "--reference", dest="reference",action="store_true",default=False)
(self.options, self.args) = parser.parse_args()
self.firstPass = True
# Make sure target directories do exist
import os
self.screenshotDir = "./Screenshots"
self.referenceDir = "./ReferenceScreenShots"
if (not os.path.exists(self.screenshotDir)):
os.makedirs(self.screenshotDir)
if (not os.path.exists(self.referenceDir)):
os.makedirs(self.referenceDir)
# Empty existing screenshots
pythonProgramName = os.path.splitext(os.path.basename(sys.argv[0]))[0]
if (self.firstPass == True):
targetDir = self.screenshotDir
startString = "SCREENSHOT_"
if self.options.reference:
targetDir = self.referenceDir
startString = "REFERENCE_"
for entry in (os.listdir(targetDir)):
if (entry.find(startString+pythonProgramName)==0):
os.unlink(targetDir+'/'+entry)
print "Deleting: ",targetDir+'/'+entry
def frameEnded(self,frameEvent):
###################
# Testing factory #
###################
def partialScreenShot(box,targetFile):
# Get temporary file name for full size screenshot
import tempfile
(handle,tmpFile) = tempfile.mkstemp(prefix="Screenshot_",suffix=".PNG")
os.close(handle)
# Make screenshot
self.renderWindow.writeContentsToFile(tmpFile)
# Extract needed zone
import Image
im = Image.open(tmpFile)
cropppedImage = im.crop(box)
# Save to final file
cropppedImage.save(targetFile)
# Remove temp file
if (os.path.exists(tmpFile)):
os.unlink(tmpFile)
return(True)
if (self.options.test == True) or (self.options.reference == True):
# Make sure self.previousFactor is defined
try:
self.previousFactor
except:
self.previousFactor = None
# Check if factor has changed
if (self.factor != self.previousFactor):
# Define screenshot names
import os
pythonProgramName = os.path.splitext(os.path.basename(sys.argv[0]))[0]
baseName = '_'+pythonProgramName
baseName += '_'+'FACTOR=%05f' % self.factor
baseName.replace(".","dot")
baseName += '.PNG'
screenshotFullName = self.screenshotDir+'/'+"SCREENSHOT"+ baseName
referenceFullName = self.referenceDir +'/'+"REFERENCE" + baseName
# Make screenshots
box = (0,0,800,400)
if (self.options.reference):
# Create a new reference
partialScreenShot(box,referenceFullName)
print "NEW_REFERENCE: ",referenceFullName
else:
# Make screenshot
partialScreenShot(box,screenshotFullName)
print "SCREENSHOT:",screenshotFullName
# Exit when all tests are completed
if (self.factor == 1.0):
print "Screenshots dumped"
quit()
# Get ready for next factor
self.previousFactor = self.factor
return True
Complete source files can be downloaded here:
http://chpod.free.fr/screenshots/20081106_Demo_Bezier.py
http://chpod.free.fr/screenshots/20081106_autotest.py
This a just a first and basic try. It shows that autotesting can be implemented quite easily, without the need to rewrite the demos from scratch.
Right now, I am trying to get rid of the "Rendering subsystem" window. I would like to be able to control those settings from the command line. Does anyone know how to do this?
Any input greatly appreciated,
Thanks,
chpod