سؤال

أنا أكتب نسخة من بايثون doctest عداء الاختبار, لماتلاب (يعمل جزئيا...).لكي ينجح هذا، أحتاج إلى تشغيل التعليمات البرمجية في أمثلة الأشخاص في تعليمات ملف m الخاص بهم.أريد أن تنتقل المتغيرات من سطر إلى آخر، على سبيل المثال.

% >> I = 5 + 33; % expect no output
% >> I
% 
% I =
% 
%     38
%

لإجراء الاختبارات، لدي حلقة فوق التطابقات مع REGEX التي تبحث عن الاختبارات.لكل مباراة أنا evalc المثال وتأكد من تطابق النتيجة:

for I = 1:length(examples)
    try
        got = evalc(examples(I).source);
    catch exc
        got = ['??? ' exc.message];
    end

    % process the result...
end

المشكلة هي أن تعريف المثال لـ I لقد قام الآن بضرب متغير الحلقة في حلقتي, ، نظرًا لأن المهام تنتقل من eval إلى النطاق الخارجي.لقد بحثت حولي عن شيء قادر على إنشاء نطاق/مساحة عمل جديدة، ولكن evalin يمكن فقط إعادة استخدام مساحة عمل المتصل، وهو الأمر الأسوأ.لقد فكرت أيضًا في خيارات استدعاء وظيفة فرعية أو save/load, ، لكنني لم أصل إلى أي مكان، لكن ربما لم أفكر مليًا بما فيه الكفاية.

لذلك أعتقد أنني بحاجة فقط إلى تسمية جميع المتغيرات الخاصة بي doctest__system__* والتعايش مع مشاكل مساحة الاسم ...إلا إذا كان لديك فكرة أخرى ل استراتيجية لتجنب تعارضات الأسماء المتغيرة?

هل كانت مفيدة؟

المحلول

مشروع مثير للاهتمام بالتأكيد..أعتقد أن أفضل خيار لديك هو كتابة دالة منفصلة لتنفيذ الاختبارات، واستخدام بادئة فريدة لجميع المتغيرات داخل هذه الوظيفة لتجنب تعارض الأسماء.وهنا محاولتي في هذا:

function [PREFIX_b varargout] = testContext(PREFIX_src, PREFIX_srcOutput)
    %# TESTCONTEXT   Executes the source code and tests for
    %#               equality against the expected output
    %#
    %#   Input:
    %#       PREFIX_src       - source to execute, cellarry of statements
    %#       PREFIX_srcOutput - output to expect, cellarray of output of each statement
    %#
    %#   Output:
    %#       PREFIX_b         - true/false for success/failure of test
    %#                          note that the output is strtrim()'ed then strcmp()'ed
    %#       varargout{1}     - variable names assigned in this confined context
    %#       varargout{2}     - variable values assigned
    %#
    %#   Example 1:
    %#       source = { 'I = 5+33;' 'I' };
    %#       output = { [], ['I =' char(10) '    38'] };
    %#       b = testContext(source, output);
    %#
    %#   Example 2:
    %#       source = { 'I = 5+33; J = 2;' 'K = 1;' 'disp(I+J+K)' };
    %#       output = { [], [], '41' };
    %#       [b varNames varValues] = testContext(source, output);
    %#
    %#   See also: eval evalc
    %#

    PREFIX_b = true;

    try
        %# for each statement
        for PREFIX_i=1:numel(PREFIX_src)
            %# evaluate
            PREFIX_output = evalc( PREFIX_src{PREFIX_i} );
            PREFIX_output = strtrim(PREFIX_output);            %# trim whitespaces
            %# compare output
            if ~isempty( PREFIX_srcOutput{PREFIX_i} )
                if ~strcmp(PREFIX_output,PREFIX_srcOutput{PREFIX_i})
                    PREFIX_b = false;
                    return
                end
            end
        end

        if nargout > 1
            %# list created variables in this context
            %#clear ans
            PREFIX_vars = whos('-regexp', '^(?!PREFIX_).*');   %# java regex negative lookahead
            varargout{1} = { PREFIX_vars.name };

            if nargout > 2
                %# return those variables
                varargout{2} = cell(1,numel(PREFIX_vars));
                for PREFIX_i=1:numel(PREFIX_vars)
                    [~,varargout{2}{PREFIX_i}] = evalc( PREFIX_vars(PREFIX_i).name );
                end
            end
        end

    catch ME
        warning(ME.identifier, ME.message)
        PREFIX_b = false;
        varargout{1} = {};
        varargout{2} = {};
    end
end

أفترض أنك قادر على تحليل ملف m لاستعادة الأمثلة للاختبار، حيث يكون لديك كل عبارة مع مخرجاتها المتوقعة.

على سبيل المثال، فكر في هذا الاختبار البسيط المضمن في رأس الوظيفة:

I = 5 + 33;
J = 2*I;
disp(I+J)

وبما أن العبارة الأخيرة فقط لها مخرجات، فإننا نختبرها على النحو التالي:

source = {'I = 5 + 33;' 'J = 2*I;' 'disp(I+J)'};
output = {[], [], '114'};
[b varNames varValues] = testContext(source, output)

النتائج:

b =
     1
varNames = 
    'I'    'J'
varValues = 
    [38]    [76]

يوضح ما إذا كان الاختبار قد نجح أو فشل.اختياريًا، تقوم الدالة بإرجاع قائمة بالمتغيرات التي تم إنشاؤها في هذا السياق بالإضافة إلى قيمها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top