IDL中的单元测试
原文链接: https://www.nv5geospatialsoftware.com/Learn/Blogs/Blog-Details/unit-testing-in-idl
12741 文章评分:
3.7
IDL中的单元测试
匿名 2015年5月7日 星期四
软件开发的关键环节之一就是测试。确保软件在多种输入下都能按预期运行,对于创建健壮且可维护的代码至关重要。在IDL中进行测试可能有些棘手,通常需要您自己实现一套维护测试的系统。不过,借助一个简单的框架,这项任务会变得轻松很多。
在深入框架之前,建议您先阅读关于测试驱动开发(Test Driven Development)以及编写优质测试的相关概念。网上有许多优秀的教程和概述,它们能很好地强调测试的重要性。现在,让我们开始看代码!
假设我们想编写一个函数 CONVERT_TO_STRING。由于我们是从零开始编写这个函数,让我们先定义函数的“契约”。它接收一个IDL变量作为输入,将其转换为具有自定义格式的字符串,然后返回。很好,让我们编写一些测试。
test_convert_to_string.pro:
pro test_convert_to_string_number
compile_opt idl2
on_error, 2
input = 1
expect = '1'
result = convert_to_string(input)
if result ne expect then begin
message, 'Converting number failed.'
endif
end
pro test_convert_to_string_null
compile_opt idl2
on_error, 2
input = !NULL
expect = '!NULL'
result = convert_to_string(input)
if result ne expect then begin
message, 'Converting number failed.'
endif
end
pro test_convert_to_string_object
compile_opt idl2
on_error, 2
input = hash('a',1,'b',2,'c',3)
expect = '{"c":3,"a":1,"b":2}'
result = convert_to_string(input)
if result ne expect then begin
message, 'Converting number failed.'
endif
end
pro test_convert_to_string
compile_opt idl2
print
print, 'Testing suite for convert_to_string()'
end
在编写任何代码之前,我们已经有测试用例了。我们之所以可以这样做,是因为我们定义了函数的“契约”。我们清楚地知道函数应该接收什么输入,以及输出应该是什么。现在,运行这些代码可能有点繁琐,所以让我们设置一些框架。
unit_test_runner.pro:
; Path – 测试目录的路径
pro unit_test_runner, path
compile_opt idl2
if ~file_test(path, /directory) then begin
message, 'Input must be a path.'
endif
test_files = file_search(path, 'test*.pro')
resolve_routine, file_basename(test_files,'.pro'), /compile_full_file
tests = routine_info()
print
print,'--------------------------------------------------------------------------------'
error_count = 0
for i=0, tests.*length*-1 do begin
catch, errorStatus
if (errorStatus ne 0) then begin
catch, /cancel
print, 'ERROR: ', !ERROR_STATE.*msg*
i++
error_count++
continue
endif
if (tests[i]).startswith('TEST_') then begin
call_procedure, tests[i]
endif
endfor
print
print,'--------------------------------------------------------------------------------'
print
if error_count gt 0 then begin
print, 'Unit test failures on: ' + path
endif else begin
print, 'Unit tests pass.'
endelse
end
现在我们要做的就是给 UNIT_TEST_RUNNER 一个指向我们测试文件的路径,它就会运行它们!让我们开始专心编码。
convert_to_string.pro:
; Input - IDL 变量
; Output - 变量的自定义字符串表示
function convert_to_string, var
compile_opt idl2
switch size(var,/TYPE) of
0: begin
return, '!NULL '
break
end
11: begin
if isa(var,'HASH') or isa(var,'DICTIONARY') or isa(var,'ORDEREDHASH') then begin
return, json_serialize(var)
endif
break
end
else: begin
return, strtrim(var,2)
end
endswitch
end
现在运行我们的测试套件:
--------------------------------------------------------------------------------
Testing suite for convert_to_string()
% Compiled module: CONVERT_TO_STRING.
ERROR: TEST_CONVERT_TO_STRING_NULL: Converting !NULL failed.
--------------------------------------------------------------------------------
Unit test failures on: C:\convert_to_string
哎呀!我们的 !NULL 情况返回的值不符合预期(好在这是个容易修复的问题)。
通过采用测试先行的开发方式,您被迫去思考每个函数的“契约”(输入/输出)。通过针对此契约实现单元测试,我们就可以有信心地使用新函数。如果所有代码都有单元测试,那么代码中出现的任何问题都能轻松地被识别和修复。
注意:请确保每个代码段都保存到指定的文件中(文件名已在代码前给出),并且所有文件都在您的 IDL 路径(IDL PATH)中。
Landsat Program Well Worth It's Price Tag Use ENVI and DigitalGlobe Data to Help Recovery Efforts in Nepal