Skip to content
Snippets Groups Projects
Commit c1e9cd3c authored by Olivier Bertrand's avatar Olivier Bertrand
Browse files

Add blender unit testing

A console script has been added, blendunittest,  to run unittest under blender.
The blender unittesting file should start by blendtest, and be formatted according to unittesting convention.
parent 365fea82
No related branches found
No related tags found
No related merge requests found
File added
"""
Unittesting under blender
"""
import unittest
import numpy as np
from navipy.sensors.renderer import BlenderRender
class TestBlenderRender(unittest.TestCase):
@classmethod
def setUpClass(self):
self.cyberbee = BlenderRender()
def test_class_assigments_error(self):
""" Test that error are correctly raised
List of tested function:
* camera_rotation_mode
* cycle_samples
* camera_fov
* camera_gaussian_width
* camera_resolution
"""
with self.assertRaises(TypeError):
# Should a string
self.cyberbee.camera_rotation_mode = 0
with self.assertRaises(TypeError):
# Should be an integer
self.cyberbee.cycle_samples = 0.1
with self.assertRaises(TypeError):
# Should be a tuple list or np.ndarray
self.cyberbee.camera_fov = 'bla'
with self.assertRaises(TypeError):
# Should be a float or int, so not a complex
self.cyberbee.camera_gaussian_width = 4 + 4j
with self.assertRaises(TypeError):
# Should be a tuple, list or nd.array
self.cyberbee.camera_resolution = 'bla'
def test_class_assigments(self):
""" Test set/get match
* camera_rotation_mode
* cycle_samples
* camera_fov
* camera_gaussian_width
* camera_resolution
"""
# camera cycle_samples
val = 100
self.cyberbee.cycle_samples = val
self.assertEqual(val, self.cyberbee.cycle_samples)
# camera rotation mode
val = 'XYZ'
self.cyberbee.camera_rotation_mode = val
self.assertEqual(val, self.cyberbee.camera_rotation_mode)
# camera fov
val = np.array([[-90, 90], [-180, 180]])
self.cyberbee.camera_fov = val
np.testing.assert_allclose(val, self.cyberbee.camera_fov)
# camera gaussian
val = 1.5
self.cyberbee.gaussian_width = val
self.assertEqual(val, self.cyberbee.gaussian_width)
# camera resolution
val = np.array([360, 180])
self.cyberbee.camera_resolution = val
np.testing.assert_allclose(val, self.cyberbee.camera_resolution)
"""
"""
import unittest
import sys
import argparse
import pkg_resources
import tempfile
import os
import inspect
def parser_blendnavipy():
# Create command line options
parser = argparse.ArgumentParser()
arghelp = 'Path to the environment (.blend) in which your agent lives'
defaultworld = pkg_resources.resource_filename(
'navipy', 'resources/twocylinders_world.blend')
parser.add_argument('--blender-world',
type=str,
default=defaultworld,
help=arghelp)
arghelp = 'Path to start searching for blendtest*.py'
parser.add_argument('--start-dir',
type=str,
default='navipy',
help=arghelp)
arghelp = 'Command to run blender\n'
arghelp += 'If not provided, the script will try to find the command'
arghelp += " by using: shutil.which('blender')"
parser.add_argument('--blender-command',
type=str,
default=None,
help=arghelp)
arghelp = 'To display some stuff \n'
arghelp += ' * -v print command \n'
arghelp += ' * -vv print also script'
parser.add_argument('-v', '--verbose',
action='count',
default=0,
help=arghelp)
return parser
def run(start_dir):
suite = unittest.defaultTestLoader.discover(start_dir=start_dir,
pattern='blendtest*.py')
success = unittest.TextTestRunner().run(suite).wasSuccessful()
print(success)
if not success:
raise Exception('Tests Failed')
def main():
# encoding for temporary file
encoding = 'utf-8'
# Fetch arguments
args = parser_blendnavipy().parse_args()
# Create tempfile with testing code and then call blendnavipy
header = '# Generated by {}\n'.format(sys.argv[0])
with tempfile.NamedTemporaryFile() as tfile:
# Start of file
tfile.write(header.encode(encoding))
tfile.write('import unittest \n'.encode(encoding))
for line in inspect.getsourcelines(run)[0]:
tfile.write(line.encode(encoding))
tfile.write('\n\n'.encode(encoding))
tfile.write('try:\n'.encode(encoding))
tfile.write(' run("{}")\n'.format(args.start_dir).encode(encoding))
tfile.write(' sys.exit(0)\n'.encode(encoding))
tfile.write('except Exception:\n'.encode(encoding))
tfile.write(' sys.exit(1)\n'.encode(encoding))
tfile.seek(0)
command = 'blendnavipy --blender-world {} --python-script {}'
command = command.format(args.blender_world, tfile.name)
if args.blender_command is not None:
command += ' --blender-command {}'.format(args.blender_command)
for _ in range(args.verbose):
command += ' -v'
os.system(command)
if __name__ == "__main__":
# execute only if run as a script
main()
...@@ -136,23 +136,23 @@ class BlenderRender(): ...@@ -136,23 +136,23 @@ class BlenderRender():
"""get fov of camera """get fov of camera
:returns: the field of view of the camera as \ :returns: the field of view of the camera as \
[min,max],[longitude,latitude] in degrees [[minimum latitude, maximum latitude],
:rtype: dict [minimum longitude, maximum longitude]]
(in deg)
:rtype: np.array
..todo Change assert to if -> raise TypeError/KeyError ..todo Change assert to if -> raise TypeError/KeyError
""" """
if self.camera.data.type != 'PANO': if not self.camera.data.type == 'PANO':
raise TypeError('Camera is not panoramic') raise TypeError('Camera is not panoramic')
if self.camera.cycles.panorama_type == 'EQUIRECTANGULAR': if not self.camera.data.cycles.panorama_type == 'EQUIRECTANGULAR':
raise TypeError('The panoramic camera is not equirectangular') raise TypeError('The panoramic camera is not equirectangular')
fov = dict() fov = np.zeros((2, 2))
fov['latitude_min'] = np.rad2ged(self.camera.data.cycles.latitude_min) fov[0, 0] = np.rad2deg(self.camera.data.cycles.latitude_min)
fov['latitude_max'] = np.rad2ged(self.camera.data.cycles.latitude_max) fov[0, 1] = np.rad2deg(self.camera.data.cycles.latitude_max)
fov['longitude_min'] = np.rad2ged( fov[1, 0] = np.rad2deg(self.camera.data.cycles.longitude_min)
self.camera.data.cycles.longitude_min) fov[1, 1] = np.rad2deg(self.camera.data.cycles.longitude_max)
fov['longitude_max'] = np.rad2ged(
self.camera.data.cycles.longitude_max)
return fov return fov
@camera_fov.setter @camera_fov.setter
......
...@@ -41,10 +41,11 @@ setup_dict = {'name': 'navipy', ...@@ -41,10 +41,11 @@ setup_dict = {'name': 'navipy',
'networkx', 'networkx',
'sphinx-argparse'], 'sphinx-argparse'],
'package_data': {'navipy': ['resources/database.db', 'package_data': {'navipy': ['resources/database.db',
'resources/forest_world.blend']}, 'resources/*.blend']},
'include_package_data': True, 'include_package_data': True,
'entry_points': { 'entry_points': {
'console_scripts': [ 'console_scripts': [
'blendnavipy=navipy.sensors.blendnavipy:main']}, } 'blendnavipy=navipy.sensors.blendnavipy:main',
'blendunittest=navipy.sensors.blendunittest:main']}, }
setup(**setup_dict) setup(**setup_dict)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment