Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
4 / 4 / 1
Регистрация: 17.02.2015
Сообщений: 64
1

Юнит-тесты: приложение, считающее количество слов с заданной буквой в текстовом файле через тестирование

08.03.2015, 23:43. Показов 2508. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
необходимо разработать приложение, считающее количество слов с заданной буквой в текстовом файле через тестирование. В голову приходит только тест в виде заданного проверочного предложения, передачи его в виде аргумента в функцию и сравнение полученного результата с ожидаемым. Но это как-то слишком просто выглядит. Какие еще могут быть тесты для данной задачи? Заранее спасибо за помощь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.03.2015, 23:43
Ответы с готовыми решениями:

В текстовом файле посчитать количество слов, начинающихся и заканчивающихся одной и той же буквой (нужны комментарии)
Программа предназначена для подсчитывания в текстовом файле количества слов начинающихся и...

В текстовом файле подсчитать количество строк, которые оканчиваются буквой «в»
В текстовом файле подсчитать количество строк, которые оканчиваются буквой «в». Вообще не умею...

В текстовом файле подсчитать количество строк которые начинаются и оканчиваются одной и той же буквой
В текстовом файле подсчитать количество строк которые начинаются и оканчиваются одной и той же...

В текстовом файле подсчитать количество строк, которые начинаются и заканчиваются одной и той же буквой
Не подскажете, в чем ошибка? :) Программа не правильно считает. #include <stdio.h> #include...

9
542 / 163 / 79
Регистрация: 23.09.2013
Сообщений: 316
09.03.2015, 00:17 2
Лучший ответ Сообщение было отмечено IT_Beginner как решение

Решение

Я вижу как минимум 3 разных модуля:
1) Класс, который считывает всё содержимое файла и представляет его в виде строки.
Тесты:
Если в файл записано 1 слово функция считывания вернет это слово
Если в файл записано много слов, функция вернет эти слова
Если файл пуст, функция вернет пустую строку
Если файл не найден, функция вернет пустую строку
2) Класс, который по входной строке подсчитывает количество слов с заданной буквой,
Тесты:
Одно слово, содержащее букву, функция вернула 1
Одно слово, не содержащее букву, функция вернула 0
Два слова, содержащие букву, функция вернула 2
Три слова, два из которых содержат букву, функция вернула 2
Пустая строка, функция вернула 0

3) Класс принимает интерфейсы считывания, подсчета, мб записи в поток и оперирует с ними
Тесты:
Если не передан один из интефейсов кидается исключение или срабатывает ассерт
Когда вызывается метод подсчитать число слов с заданной буквой в файле - вызывается интерфейс считывания файла с путем, переданным в качестве аргумента
Полученный текст из интерфейса считывания подается на вход интерфейсу подсчета
В интерфейс подсчета передается буква, которая задана при вызове метода подсчета числа слов
Результат подсчета подается на вход интерфейсу записи в поток

Тесты 2 и 3 - системно не зависимые, можно их считать юнит тестами
Тест 1 - зависит от файловой системы.
Можно создать еще акссептанс тест, который вызывает программу сконфигурированную для использования конкретных реализаций классов, передает ей путь до файла, в котором ожидается например 5 слов с буквой b, и 10 слов с буквой a - и ожидает, что выведен будет текст с такими данными.
1
4 / 4 / 1
Регистрация: 17.02.2015
Сообщений: 64
09.03.2015, 02:44  [ТС] 3
ого, спасибо большое, пошел пробовать реализовать. Будут трудности - дальше буду спрашивать уже с кодом

Добавлено через 2 часа 18 минут
если не трудно - с третьей частью не совсем понятно что куда идет, можно подробнее? Пока что вырисовывается нечто такое
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
 
namespace ACounterUnitTest
{       
    TEST_CLASS(UnitTestReader)
    {
    public:
        
        TEST_METHOD(TestMethod1)
        {
            Reader read;
            FILE * test1 = fopen("empty.txt","r");
            FILE * test2 = fopen("oneWordNoA.txt", "r");
            FILE * test3 = fopen("threeWordsTwoA.txt", "r");
            FILE * test4 = fopen("notExisted.txt", "r");
 
            char *t1;
            char *t2 = "word";
            char *t3 = "three awords abroad";
            char *t4;
 
            Assert::AreSame(*t1, read.readfile(test1));
            Assert::AreSame(*t2, read.readfile(test2));
            Assert::AreSame(*t3, read.readfile(test3));
            Assert::AreSame(*t4, read.readfile(test4));
        }
 
    };
 
    TEST_CLASS(UnitTestACounter)
    {
    public:
 
        TEST_METHOD(TestMethod1)
        {
            ACounter aCount;
            char *t1 = "aword";
            char *t2 = "word";
            char *t3 = "aword abroad";
            char *t4 = "test aword abroad";
            char *t5;
 
            Assert::AreSame(1, aCount.aCounter(t1));
            Assert::AreSame(0, aCount.aCounter(t2));
            Assert::AreSame(2, aCount.aCounter(t3));
            Assert::AreSame(2, aCount.aCounter(t4));
            Assert::AreSame(0, aCount.aCounter(t5));
        }
 
    };
    TEST_CLASS(UnitTestGeneral)
    {
    public:
 
        TEST_METHOD(TestMethod1)
        {
 
        }
 
    };
}

может есть какие замечания?
0
37 / 37 / 18
Регистрация: 15.05.2013
Сообщений: 236
09.03.2015, 06:46 4
Лол, тебе везет. Как раз именно сегодня первый раз для себя открыл юнит-тестирование.
P. S. Этот же человек обращался за помощью в решение задачи вычисления кол-ва определенных букв/слов в файле. Я использовал гуглфреймворк, но думаю у тебя пока маленький скилл.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <fstream>
#include <map>
 
using namespace std;
 
map<string, long long> split(const string& str, const string& delimiters);
long long substr_count_word(const string& haystack, const string& needle);
 
int main(int argc, char *argv[])
{
    string DIR = "D:\\1.txt";
    ifstream fin(DIR);
 
    string str;
    fin.seekg(0, ios::end);
    size_t size = fin.tellg();
 
    str.reserve(size);
    fin.seekg(0, ios::beg);
 
    str.assign((istreambuf_iterator<char>(fin)),
             istreambuf_iterator<char>());
 
    map<string, long long> test = {
        {"the",43},
        {"and",20},
        {"his",20},
        {"in",14},
        {"", 0}
    };
 
    for(auto it : test) {
        string needle = it.first;
 
        long long expected = it.second;
        long long actual =  substr_count_word(str, needle);
 
        if(expected == actual)
            cout << "needle = " << needle <<
                    ", expected = "  << expected
                 << ", actual = " << actual
                 << "\texpected == actual - TRUE" << endl;
        else
            cout << "needle = " << needle <<
                    ", expected = "  << expected
                 << ", actual = " << actual
                 << "\texpected != actual - FALSE" << endl;
    }
 
 
    return 0;
}
 
map<string, long long> split(const string& str, const string& delimiters) {
    if(str.empty()) return map<string, long long>();
    if(delimiters.empty()) return map<string, long long>();
 
    size_t lastPos = str.find_first_not_of(delimiters, 0);
    size_t pos = str.find_first_of(delimiters, lastPos);
 
    map<string, long long> tokens;
    while (string::npos != pos || string::npos != lastPos) {
        string token = str.substr(lastPos, pos - lastPos);
        tokens[token]++;
        lastPos = str.find_first_not_of(delimiters, pos);
        pos = str.find_first_of(delimiters, lastPos);
    }
 
    return tokens;
}
 
long long substr_count_word(const string& haystack, const string& needle) {
    if(haystack.empty()) return 0;
    if(needle.empty()) return 0;
 
    map<string, long long> words = split(haystack, " -,.;:!?\r\n\"");
    return words[needle];
}
1
542 / 163 / 79
Регистрация: 23.09.2013
Сообщений: 316
09.03.2015, 10:11 5
Лучший ответ Сообщение было отмечено IT_Beginner как решение

Решение

IT_Beginner,

По текущему:
1) названия тестов должны отражать то, что они проверяют
2) каждый тест должен документировать только одно поведение
3) имена переменных в тесте должны быть согласованны с именем теста
4) все тестируемые переменные должны быть явным образом инициализированны
5) в теле теста, если это возможно, должны быть явным образом выделены три секции arrange act assert
6) те конкретные значения, которые не имеют ключевого значения (а какой именно там путь, главное что до пустого файла) - должны быть скрыты за константными переменными.
7) Имена переменных, вызываемых методов, передаваемых аргументов, объектов должны быть согласованны
8) почему вы решили не включать fopen в reader?
9) почему вы решили часть механизма открытия файлов (через FILE*) оставить открытым через сигнатуру reader-а?
10) почему вы не захотели использовать плюсовые стримы для реализации чтения из файла?

Например:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <iostream>
#include <string>
 
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
 
namespace RenameMePls
{
    TEST_CLASS(ReaderTest)
    {
    public:
 
        static const std::string kFileWithOneWordPath = "one_word.txt";
        static const std::string kFileWithAlotOfWordsPath = "alot_of_word.txt";
        static const std::string kEmptyFilePath = "empty.txt";
        static const std::string kNoExistingPath = "not/existing.txt";
 
        TEST_METHOD(WhenFileContainsOneWordReadTextWillReturnStringWithThisWord)
        {
            Reader reader;
 
            auto returned_string = reader.ReadText(kFileWithOneWordPath);
 
            Assert::AreSame(kTheOnlyWordThatFileContains, returned_string);
        }
 
 
        TEST_METHOD(WhenFileContainsAlotOfWordsReadTextWillReturnStringWithAllThisWord)
        {
            Reader reader;
 
            auto returned_string = reader.ReadText(kFileWithAlotOfWordsPath);
 
            Assert::AreSame(kStringWithAlotOfWordsFromFile, returned_string);
        }
 
        TEST_METHOD(WhenFileIsEmptyReadTextWillReturnEmptyString)
        {
            Reader reader;
 
            auto returned_string = reader.ReadText(kEmptyFilePath);
 
            Assert::AreSame(kEmptyString, returned_string);
        }
 
        TEST_METHOD(WhenFileIsNotExistsByPathReadTextWillReturnEmptyString)
        {
            Reader reader;
 
            auto returned_string = reader.ReadText(kNoExistingPath);
 
            Assert::AreSame(kEmptyString, returned_string);
        }
 
    };
 
    TEST_CLASS(ACounterTest)
    {
    public:
 
        static const std::string kWordWithLetterA = "word_with_a";
        static const std::string kWordWithLetterB = "word_with_B";
        static const std::string kWordWithoutLetterA = "word_without_letter";
        static const std::string kTwoWordsWithLetterA =
            kWordWithLetterA + " " + kWordWithLetterA;
        static const std::string kThreeWordsOnltyTwoContainingLetterA =
            kTwoWordsWithLetterA + " " + kWordWithoutLetterA;
 
 
        TEST_METHOD(WhenTextContainsOneWordContaingLetterCountWordsWithLetterWillReturnOne)
        {
          Counter counter;
 
          auto number_of_words = conter.CountWordsWithLetter('a', kWordWithLetterA);
 
          Assert::AreSame(1, number_of_words);
        }
 
        TEST_METHOD(WhenTextContainsOneWordContaingLetterInUpperCaseCountWordsWithLetterWillReturnOne)
        {
          Counter counter;
 
          auto number_of_words = conter.CountWordsWithLetter('B', kWordWithLetterInUpperCaseB);
 
          Assert::AreSame(1, number_of_words);
        }
 
 
        TEST_METHOD(WhenTextContainsOneWordWithoutLetterCountWordsWithLetterWillReturnZero)
        {
          Counter counter;
 
          auto number_of_words = conter.CountWordsWithLetter('a', kWordWithoutLetterA);
 
          Assert::AreSame(0, number_of_words);
        }
 
        TEST_METHOD(WhenTextContainsTwoWordsContaingLetterCountWordsWithLetterWillReturnTwo)
        {
          Counter counter;
 
          auto number_of_words = conter.CountWordsWithLetter('a', kTwoWordsWithLetterA);
 
          Assert::AreSame(2, number_of_words);
        }
 
        TEST_METHOD(WhenTextContainsThreeWordsAnOnlyTwoContaingLetterCountWordsWithLetterWillReturnTwo)
        {
          Counter counter;
 
          auto number_of_words = conter.CountWordsWithLetter('a', kThreeWordsOnltyTwoContainingLetterA);
 
          Assert::AreSame(2, number_of_words);
        }
 
        TEST_METHOD(WhenTextContainsThreeWordsAnOnlyTwoContaingLetterCountWordsWithLetterWillReturnTwo)
        {
          Counter counter;
 
          auto number_of_words = conter.CountWordsWithLetter('a', kThreeWordsOnltyTwoContainingLetterA);
 
          Assert::AreSame(2, number_of_words);
        }
 
 
    };
}
1
4 / 4 / 1
Регистрация: 17.02.2015
Сообщений: 64
09.03.2015, 14:35  [ТС] 6
Такой вопрос, в первой части тестов, с чем сравнивает Assert? Имею ввиду kTheOnlyWordThatFileContains и др. Вместе с файлами объявить и проверочные string?
0
542 / 163 / 79
Регистрация: 23.09.2013
Сообщений: 316
09.03.2015, 15:10 7
IT_Beginner, да, сделать строки, которые записаны в файл и с ними сравнивать. Альтернативой будет - считывать строки из файлов - но это на мой взгляд может привести к большим ошибкам, чем просто наличие строки и файла, которому она соответствует.
0
37 / 37 / 18
Регистрация: 15.05.2013
Сообщений: 236
09.03.2015, 15:22 8
Лучший ответ Сообщение было отмечено IT_Beginner как решение

Решение

Какие ужасы

В гуглфреймворке всё гораздо проще. Я первый раз писал и доку ещё не изучал.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <fstream>
#include <map>
#include <gtest/gtest.h>
 
#include "functions.h"
 
using namespace std;
 
 
TEST(test001, test)
{
    string DIR = "D:\\1.txt";
    ifstream fin(DIR);
 
    string str;
    fin.seekg(0, ios::end);
    size_t size = fin.tellg();
 
    str.reserve(size);
    fin.seekg(0, ios::beg);
 
    str.assign((istreambuf_iterator<char>(fin)),
               istreambuf_iterator<char>());
 
 
    map<string, long long> test = {
        {"the",62},
        {"and",26},
        {"his",22},
        {"in",54},
        {"", 0}
    };
 
    long long expected = 0;
    long long actual =  multi_substr_count("", "");
    ASSERT_EQ(expected, actual);
 
    for(auto it : test) {
        string needle = it.first;
 
        long long expected = it.second;
        long long actual =  multi_substr_count(str, needle);
 
        ASSERT_EQ(expected, actual);
    }
}
 
 
GTEST_API_ int main(int argc, char **argv){
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
1
4 / 4 / 1
Регистрация: 17.02.2015
Сообщений: 64
09.03.2015, 16:35  [ТС] 9
Melg, спасибо, буду разбираться
Kant, выглядит красиво, но, к сожалению, мне непонятно Во-первых надо разбираться как gtest прицепить, во-вторых что за мапы и т.д. В общем, сперва надо доделать начатое, разобраться с имеющимся инструментом, еще под эти тесты сделать программу (предложенное в другой ветке решение как-то не очень коррелирует с разрабатываемыми тестами).

Добавлено через 15 минут
Melg,
C++
1
2
3
4
        static const std::string kFileWithOneWordPath = "one_word.txt";
        static const std::string kFileWithAlotOfWordsPath = "alot_of_word.txt";
        static const std::string kEmptyFilePath = "empty.txt";
        static const std::string kNoExistingPath = "not/existing.txt";
на эту часть ругается, говорит что не может быть определения внутри класса. И второй вопрос - разве там не надо добавить какой-нибудь fopen? string поймет что мы хотим прочесть из файла, а не это такая строка "text.txt"?
0
37 / 37 / 18
Регистрация: 15.05.2013
Сообщений: 236
09.03.2015, 17:17 10
Может за базу С/С++ возьмешься для начала? А потом уже тесты и всё остальное.

Язык программирования C++. Базовый курс (5-е издание)
Год: 2014
Автор: Стенли Б. Липпман, Жози Лажойе, Барбара Э. Му
0
09.03.2015, 17:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.03.2015, 17:17
Помогаю со студенческими работами здесь

Поиск слов в текстовом файле по заданной директории
Нужно написать программу, которая проверяет наличие файла по введенному с клавиатуры адресу; если...

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

В заданном файле должна подсчитывать количество слов с 1-й буквой, 2-мя, 3-мя
Здравствуйте. Программа на Си у заданном файле должна подсчитывать количество слов с 1-й буквой,...

Необходимо посчитать количество слов,оканчивающихся заданной буквой
Помогите найти ошибку вв текте программы!!Пожалуйста Необходимо посчитать количество...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru