В рассматриваемом модуле есть три условных оператора, условия для которых записаны операторами 1, 3, 6. Метод ветвей и операторов отношений будем выполнять только в последнем случае, так как первый реализован средствами.NET Framework, а второй задает условие цикла и будет протестирован позднее:
if (openBracket == -1) throw new DictionaryException(_dictionaryType, DictionaryExceptionReason.НевозможноПроанализироватьВариантыФорм);В этом случае, очевидно, достаточно рассмотреть два случая:
1) Переменная openBracket имеет значение -1, то есть строка в файле имеет неверный формат (отсутствует символ ‘(‘ как разделитель начальной формы слова и используемых форм). Тогда будет сгенерировано исключение DictionaryException, которое затем будет обработано в главном цикле программы.
2) Переменная openBracket имеет значение, отличное от -1. Тогда программа будет успешно продолжена.
Тестирование потоков данных
Определим DU-цепочки и представим их в виде информационного графа программы, наложенного на управляющий граф (см. Рисунок 5).
Рисунок 5. Наложение ИГ на УГ для модуля DictionaryParser.Parse
Получены следующие цепочки:
1) [line, 4, 8]
2) [line, 4, 10]
3) [openBracket, 5, 6]
4) [openBracket, 5, 10]
5) [initialForm, 8, 10]
Исходя из полученного списка цепочек, необходимо проанализировать поведение трех переменных (локальных переменных метод). Так как значения переменной openBracket зависит от line, а значения initialForm – от line и openBracket, то достаточно рассмотреть все требуемые варианты переменной line:
1) null
2) “”
3) Студент (Студента, Студенту, Студентом, Студенте)
4) Студент Студента Студенту Студентом Студенте
Тестирование циклов
В модуле представлен единственный цикл типа «ПОКА <условие> ВЫПОЛНЯТЬ <действие>».
Для тестировании этого цикла будем записывать в файл различные варианты справочников форм и проверим следующие варианты:
1) Единственная строка в файле
2) Две строки в файле
3) Более двух строк в файле.
Корректность записанных строк не принципиальна, так как условие некорректной записи было протестировано выше.
Набор модульных тестов.
Каждый тест сопровождается XML-комментарием, который описывает ситуацию и требуемое поведение программы.
#region Parser itself /// <summary>/// Проверяет случай отсутствия файла со справочником: все исключения перехвачены/// </summary>[Test]public static void Dictionary_FileNotFound_ExceptionCaught(){ File.Move("Data/Субъект.txt", "Data/Субъект1.txt"); Assert.Throws<DictionaryException>(() => new DictionaryParser(DictionaryType.Субъект)); File.Move("Data/Субъект1.txt", "Data/Субъект.txt");} /// <summary>/// Проверяет случай пустого файла: корректное завершение работы/// </summary>[Test]public static void Dictionary_EmptyFile_NoExceptions(){ File.Move("Data/Субъект.txt", "Data/Субъект1.txt"); File.Delete("Data/Субъект.txt"); var writer = File.CreateText("Data/Субъект.txt"); writer.Close(); DictionaryParser parser = null; Assert.DoesNotThrow(() => parser = new DictionaryParser(DictionaryType.Субъект)); Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(); CollectionAssert.AreEquivalent(parser.Dictionary, dictionary); File.Delete("Data/Субъект.txt"); File.Move("Data/Субъект1.txt", "Data/Субъект.txt");} /// <summary>/// Проверяет случай любого числа корректных строк в файле: корректное заверешение работы/// </summary>[Test]public static void Dictionary_AllLinesParsedSuccessfully_NoExceptions(){ CreateFake(); DictionaryParser parser = null; Assert.DoesNotThrow(() => parser = new DictionaryParser(DictionaryType.Субъект)); Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(); dictionary["СТУДЕНТ"] = new List<string>() {"СТУДЕНТ", "СТУДЕНТА", "СТУДЕНТУ", "СТУДЕНТОМ", "СТУДЕНТЕ"}; dictionary["СТУДЕНТЫ"] = new List<string>() {"СТУДЕНТЫ", "СТУДЕНТОВ", "СТУДЕНТАМ", "СТУДЕНТАМИ", "СТУДЕНТАХ"}; foreach (var key in dictionary.Keys) { CollectionAssert.AreEquivalent(parser.Dictionary[key].OrderBy(x => x), dictionary[key].OrderBy(x => x)); } File.Delete("Data/Субъект.txt"); File.Move("Data/Субъект1.txt", "Data/Субъект.txt");} /// <summary>/// Проверяет случай некорректной записи строки в файле: все исключения перехвачены/// </summary>[Test]public static void Dictionary_InvalidRecord_ExceptionCaught(){ File.Move("Data/Субъект.txt", "Data/Субъект1.txt"); File.Delete("Data/Субъект.txt"); var writer = File.CreateText("Data/Субъект.txt"); writer.WriteLine("Студент Студента, Студенту, Студентом, Студенте)"); writer.Close(); DictionaryParser parser = null; Assert.Throws<DictionaryException>(() => parser = new DictionaryParser(DictionaryType.Субъект)); File.Delete("Data/Субъект.txt"); File.Move("Data/Субъект1.txt", "Data/Субъект.txt");} #endregion #region Containing /// <summary>/// Проверяет случай наличия формы слова в словаре: корректное завершение работы/// </summary>[Test]public static void Dictionary_ContainsSpecificForm_NoExceptions(){ CreateFake(); DictionaryParser parser = new DictionaryParser(DictionaryType.Субъект); Assert.AreEqual(true, parser.Contains("студентов")); File.Delete("Data/Субъект.txt"); File.Move("Data/Субъект1.txt", "Data/Субъект.txt");} /// <summary>/// Проверяет случай отсутствия формы слова в словаре: корректное завершение работы/// </summary>[Test]public static void Dictionary_DoesNotContainSpecificForm_ExceptionCaught(){ CreateFake(); DictionaryParser parser = new DictionaryParser(DictionaryType.Субъект); Assert.AreEqual(false, parser.Contains("стьюдентс")); File.Delete("Data/Субъект.txt"); File.Move("Data/Субъект1.txt", "Data/Субъект.txt");} #endregion #region Initial form /// <summary>/// Проверяет случай наличия начальной формы слова в словаре: корректное завершение работы/// </summary>[Test]public static void Dictionary_InitialFormRevealed_NoExceptions(){ CreateFake(); DictionaryParser parser = new DictionaryParser(DictionaryType.Субъект); Assert.AreEqual("студенты".ToUpper(), parser.GetInitialForm("студентов")); File.Delete("Data/Субъект.txt"); File.Move("Data/Субъект1.txt", "Data/Субъект.txt");} /// <summary>/// Проверяет случай отсутствия начальной формы слова в словаре: корректное завершение работы/// </summary>[Test]public static void Dictionary_InitialFormDidNotReveal_ExceptionCaught(){ CreateFake(); DictionaryParser parser = new DictionaryParser(DictionaryType.Субъект); Assert.AreEqual("стьюдентов", parser.GetInitialForm("стьюдентов")); File.Delete("Data/Субъект.txt"); File.Move("Data/Субъект1.txt", "Data/Субъект.txt");} /// <summary>/// Проверяет случай отсутствия начальной формы слова в пустом файле: корректное завершение работы/// </summary>[Test]public static void Dictionary_InitialFormDidNotRevealFromEmptyFile_ExceptionCaught(){ File.Move("Data/Субъект.txt", "Data/Субъект1.txt"); File.Delete("Data/Субъект.txt"); var writer = File.CreateText("Data/Субъект.txt"); writer.Close(); DictionaryParser parser = new DictionaryParser(DictionaryType.Субъект); Assert.AreEqual("стьюдентов", parser.GetInitialForm("стьюдентов")); File.Delete("Data/Субъект.txt"); File.Move("Data/Субъект1.txt", "Data/Субъект.txt");} #endregion /// <summary>/// Вспомогательный метод для подготовки стандартных файлов/// </summary>private static void CreateFake(){ File.Move("Data/Субъект.txt", "Data/Субъект1.txt"); File.Delete("Data/Субъект.txt"); var writer = File.CreateText("Data/Субъект.txt"); writer.WriteLine("Студент (Студента, Студенту, Студентом, Студенте)"); writer.WriteLine("Студенты (Студентов, Студентам, Студентами, Студентах)"); writer.Close();}