Опубликован: 28.11.2007 | Уровень: специалист | Доступ: платный | ВУЗ: Национальный исследовательский ядерный университет «МИФИ»
Практическая работа 9:

Повторяемость тестирования, зависимости тестовых примеров

< Лекция 12 || Практическая работа 9: 1234 || Лекция 13 >

Как видно, несмотря на то, что третий тест операции сложения должен быть выполнен, он не проходит, хотя по первому тесту видно, что сложение работает правильно, а значение lastError точно такое же, что и во втором тесте. Это может свидетельствовать, например, о том, что при вызове метода Add в начале своей работы не очищается поле _lastError. Проведем тестирование всех функций:

try
   {
    richTextBox1.Text += "Test Case 2\n";
    richTextBox1.Text += "Входные данные: a= -2850800078, b = 3000000000\n";
    richTextBox1.Text += "Ожидаемый результат: res = 0 && error = 
                         \"Error 06\"\n";
    int res = CalcClass.Add(-2850800078, 3000000000);
    string error = CalcClass.lastError;
    richTextBox1.Text += "Код ошибки: " + error + "\n";
    richTextBox1.Text += "Получившийся результат: " + "res = " + 
                         res.ToString() + " error = " + error.ToString() + "\n";
    if (res == 0 && error == "Error 06")
    {
     richTextBox1.Text += "Тест пройден\n\n";
    }
    else
    {
     richTextBox1.Text += "Тест не пройден\n\n";
    }
   }
   catch (Exception ex)
   {
    richTextBox1.Text += "Перехвачено исключение: " + 
                         ex.ToString() + "\nТест не пройден.\n";
   }

   try
   {
    richTextBox1.Text += "Test Case 3\n(повторный тест)";
    richTextBox1.Text += "Входные данные: a= 78508, b = -304\n";
    richTextBox1.Text += "Ожидаемый результат: res = 78204 && 
                         error = \"\"" + "\n";
    int res = CalcClass.Add(78508, -304);
    string error = CalcClass.lastError;
    richTextBox1.Text += "Код ошибки: " + error + "\n";
    richTextBox1.Text += "Получившийся результат: " + "res = " + 
                         res.ToString() + " error = " + error.ToString() + "\n";
    if (res == 78204 && error == "")
    {
     richTextBox1.Text += "Тест пройден\n\n";
    }
    else
    {
     richTextBox1.Text += "Тест не пройден\n\n";
    }
   }
   catch (Exception ex)
   {
    richTextBox1.Text += "Перехвачено исключение: " + 
          ex.ToString() + "\nТест не пройден.\n";
   }

   try
   {
    richTextBox1.Text += "Test Case 4 - проверяем вычитание на корректных данных";
    richTextBox1.Text += "Входные данные: a= 78508, b = -304\n";
    richTextBox1.Text += "Ожидаемый результат: res = 78812 && 
                         error = \"\"" + "\n";
    int res = CalcClass.Sub(78508, -304);
    string error = CalcClass.lastError;
    richTextBox1.Text += "Код ошибки: " + error + "\n";
    richTextBox1.Text += "Получившийся результат: " + "res = " + 
                         res.ToString() + " error = " + error.ToString() + "\n";
    if (res == 78508 && error == "")
    {
     richTextBox1.Text += "Тест пройден\n\n";
    }
    else
    {
     richTextBox1.Text += "Тест не пройден\n\n";
    }
   }
   catch (Exception ex)
   {
    richTextBox1.Text += "Перехвачено исключение: " + 
          ex.ToString() + "\nТест не пройден.\n";
   }

   try
   {
    richTextBox1.Text += "Test Case 5 - проверяем произведение на корректных данных";
    richTextBox1.Text += "Входные данные: a= 78508, b = -304\n";
    richTextBox1.Text += "Ожидаемый результат: res = 23866432 && 
                         error = \"\"" + "\n";
    int res = CalcClass.Mult(78508, -304);
    string error = CalcClass.lastError;
    richTextBox1.Text += "Код ошибки: " + error + "\n";
    richTextBox1.Text += "Получившийся результат: " + "res = " + 
                         res.ToString() + " error = " + error.ToString() + "\n";
    if (res == 23866432 && error == "")
    {
     richTextBox1.Text += "Тест пройден\n\n";
    }
    else
    {
     richTextBox1.Text += "Тест не пройден\n\n";
    }
   }
   catch (Exception ex)
   {
    richTextBox1.Text += "Перехвачено исключение: " + 
                         ex.ToString() + "\nТест не пройден.\n";
   }
21.2.

Результат

Test Case 2
Входные данные: a= -2850800078, b = 3000000000
Ожидаемый результат: res = 0 && error = "Error 06"
Код ошибки: Error 06
Получившийся результат: res = 0 error = Error 06
Тест пройден

Test Case 3
(повторный тест) Входные данные: a= 78508, b = -304
Ожидаемый результат: res = 78204 && error = ""
Код ошибки: Error 06
Получившийся результат: res = 78204 error = Error 06
Тест не пройден

Test Case 4 — проверяем вычитание на корректных данных
Входные данные: a= 78508, b = -304
Ожидаемый результат: res = 78812 && error = ""
Код ошибки: Error 06
Получившийся результат: res = 78812 error = Error 06
Тест не пройден

Test Case 5 — проверяем произведение на корректных данных
Входные данные: a= 78508, b = -304
Ожидаемый результат: res = 23866432 && error = ""
Код ошибки: Error 06
Получившийся результат: res = -23866432 error = Error 06
Тест не пройден

Мы видим, что ни один из методов не очищает поле _lastError. Это может быть либо ошибкой проектирования, либо неправильной реализацией свойства lastError. Можно либо отправить на доработку все методы и функциональные требования, указав в них, что методы должны перед началом работы очищать свойство lastError, либо доработать свойство следующим образом:

public static string lastError
 {
   get
    {
     string temp = _lastError;
     _lastError = "";
     return temp;
    }
 }

Таким образом, после любого чтения этой переменной, её значение снова будет равняться пустой строке.

Замечание. Несмотря на кажущуюся "притянутость" этого примера, он очень характерен. Можно вернуться к "Тестовые примеры. Классы эквивалентности. Ручное тестирование в MVSTE" и удалить строки в тестовом модуле, очищающие значение _lastError. При запуске тестов третий тест вместо перехвата исключения сообщит, что метод закончил работу с кодом ошибки 3. Причина как раз в том, что после выполнения теста 2 значение _lastError не было очищено. Это еще раз свидетельствует о том, что тестам надо созавать корректное тестовое окружение. Дальше будет приведен еще один пример неправильного построения тестового окружения.

Рассмотренный пример является довольно простым, и ошибка будет легко выявлена при тестировании. В четвертом семинаре, при написании тестового драйвера для метода RunEstimate(), мы подключали сборку My.dll:

System.IO.BinaryReader reader = new System.IO.BinaryReader
  (new System.IO.FileStream(Application.StartupPath +
    + "\\My.dll", System.IO.FileMode.Open, 
       System.IO.FileAccess.Read));
      Byte[] asmBytes = new Byte[reader.BaseStream.Length];
      reader.Read(asmBytes, 0, (Int32) reader.BaseStream.Length);
      reader.Close();
      reader = null; 
System.Reflection.Assembly assm = 
System.Reflection.Assembly.Load(asmBytes);

Может показаться, что мы выполняем лишние действия, и вместо всех этих строк кода легче применить метод System.Reflection.Assembly.LoadFile, который сразу подключит необходимую сборку по пути библиотеки.

Замечание. В Framework 2.0 метод LoadFile() объявлен как устаревший.

Дальше мы можем проводить сколько угодно тестов методов класса AnalaizerClass.

Но если нам понадобится поменять заглушку класса CalcClass (например, на ту, которая выводит на экран какие-то дополнительные сведения), то мы получим ошибку access denied, т.к. сборка уже загружена и используется процессом, и перекомпилировать её не получится.

Это другая проблема регрессионного тестирования. Здесь уже ошибка не в тестируемой программе, а в самом построении тестов и тестового окружения. Как было сказано во вступлении, нужно либо для каждого теста заново проводить инициализацию тестового окружения, либо объединять тесты в группы с общей инициализацией, но следя за тем, чтобы тесты не запускались по отдельности.

< Лекция 12 || Практическая работа 9: 1234 || Лекция 13 >
Илья Макаренко
Илья Макаренко

Добрый день.

Вопрос №1

Какова стоимость получения диплома о мини-МБА по данному курсу? Или ориентироваться на указанную на сайте?

Вопрос №2

Возможно ли начать обучение без потери результатов, не отправив документы на зачисление, а отправку выполнить позже?

Александр Медов
Александр Медов

Здравствуйте, какова полная сумма предоставленной услуги с печатью документа и отправкой по почте?

Евгений Летенков
Евгений Летенков
Россия, Москва, РУДН, 2005
Алексей Корзинин
Алексей Корзинин
Россия