Как генерировать тестовые данные в соответствии с логическим выражением?

В качестве субъекта я хотел бы сгенерировать тестовые данные, чтобы охватить все возможные условия для некоторого логического выражения, как показано ниже:

 ((a==3000710)||(b==3000700))
   &&(b>=30 && b<=33)
   &&((c==1)||(c>=4 && c<=6))
   &&((v==1.0.9)||(v==2.0.0))

Любой комментарий приветствуется.

Кстати, логическое выражение — это упрощенное правило, которое применяется на нашем внутреннем сервере.


person user940178    schedule 04.07.2017    source источник
comment
Вы должны указать используемую технологию, чтобы другие могли указать вам на соответствующие ресурсы. Какой язык программирования и среду тестирования вы используете?   -  person vijoc    schedule 04.07.2017
comment
На самом деле меня не волнует язык, я просто хочу найти возможный метод (алгоритм) или инструмент с открытым исходным кодом для решения проблемы.   -  person user940178    schedule 04.07.2017


Ответы (1)


Первое, что я должен сказать - рефакторинг! Разбейте его на несколько операторов if, которые будет легче проверить, изменить логику и выйти раньше. Трудно дать более подробные предложения, не видя фактического кода и контекста.

Другое дело, если (b == 3000700), то &&(b>=30 && b<=33) возвращает false, что делает эту часть утверждения ||(b==3000700) бессмысленной. Может быть, это должно было быть (a == 3000700)?

Что касается тестовых случаев... Опять же, не видя полного фрагмента кода и не зная контекста, немного сложно давать содержательные предложения. Но я все равно попробую.

Давайте посмотрим на «критические значения» для каждой переменной.

  • Переменная a: 3000710, любая другая
  • Переменная б: 3000700, [30, 33], any other
  • Переменная с: 1, [4, 6], any other
  • Переменная v: 1.0.9, 2.0.0, any other

Используя теорию тестирования (эквивалентное разбиение и анализ граничных значений), мы можем ограничить приведенный выше список «критических» значений.

[30, 33] => 30, 31, 33 (The value outside of this range is already covered by "any other")
[4, 6] => 4, 5, 6 (The value outside of this range is already covered by "any other". Though we did't really change anything in this case)

У Nunit есть атрибут [Combinatorial], который генерирует тестовые примеры для всех возможных комбинаций отдельных элементов данных, предоставленных для параметров теста.

*Сделаны предположения: переменные a, b, c имеют тип int, переменная v является строкой

Код будет выглядеть примерно так:

        [Test, Combinatorial]        
        public void FirstTest(
            [Values(3000710, 0)] int a, 
            [Values(30, 31, 33, 3000700, 0)] int b,
            [Values(1, 4, 5, 6, 0)] int c, 
            [Values("1.0.9", "2.0.0", "")] string v)
        {
            RunTestMethod(a, b, c, v);
        }

Вам просто нужно сохранить сгенерированные тестовые данные при выполнении теста

person buxter    schedule 10.07.2017
comment
Привет @buxter, большое спасибо за подробный ответ. Вы правы насчет значения (a == 300700), это действительно опечатка. Ваш подход рабочий. Я думаю, что мы можем сделать больше, чтобы автоматически генерировать все критические значения, используя некоторые технические средства, такие как статический анализ программы, но я не знаком с этими полями, можете ли вы пролить свет на этот вопрос? Спасибо еще раз. - person user940178; 13.07.2017
comment
Это просто модульный тест на С# с использованием среды Nunit. Он имеет встроенный атрибут [Combinatorial] для параметризованного теста. Поэтому, когда тест запускается, он собирает все входные данные и генерирует все возможные варианты. В данном примере он создает все возможные вариации критических точек. Другие фреймворки модульного тестирования могут иметь что-то подобное. Надеюсь, это ответ на ваш вопрос - person buxter; 20.07.2017