Шрифт:
Test t;
while (is>>t) {
bool r = binary_search( t.seq.begin, t.seq.end, t.val);
if (r !=t.res) {
cout << "отказ: тест " << t.label
<< "binary_search: "
<< t.seq.size << "элементов, val==" << t.val
<< " –> " << t.res << '\n';
++error_count;
}
}
return error_count;
}
int main
{
int errors = test_all(ifstream ("my_test.txt");
cout << "Количество ошибок: " << errors << "\n";
}
Вот как выглядят некоторые тестовые данные.
{ 1.1 1 { 1 2 3 5 8 13 21 } 1 }
{ 1.2 5 { 1 2 3 5 8 13 21 } 1 }
{ 1.3 8 { 1 2 3 5 8 13 21 } 1 }
{ 1.4 21 { 1 2 3 5 8 13 21 } 1 }
{ 1.5 –7 { 1 2 3 5 8 13 21 } 0 }
{ 1.6 4 { 1 2 3 5 8 13 21 } 0 }
{ 1.7 22 { 1 2 3 5 8 13 21 } 0 }
{ 2 1 { } 0 }
{ 3.1 1 { 1 } 1 }
{ 3.2 0 { 1 } 0 }
{ 3.3 2 { 1 } 0 }
Здесь видно, почему мы использовали строковую метку, а не число: это позволяет более гибко нумеровать тесты с помощью десятичной точки, обозначающей разные тесты для одной и той же последовательности. Более сложный формат тестов позволяет исключить необходимость повторения одной и той же тестовой последовательности в файле данных.
26.3.2.3. Случайные последовательности
Существует один прием, который иногда помогает решить эту проблему: просто сгенерировать много случайных значений. Например, ниже приведена функция, которая записывает описание теста в поток
cout
с помощью функции randint
из раздела 24.7 и заголовочного файла std_lib.facilities.h
.
void make_test(const string& lab,int n,int base,int spread)
// записывает описание теста с меткой lab в поток cout
// генерирует последовательность из n элементов, начиная
// с позиции base
// среднее расстояние между элементами равномерно распределено
// на отрезке [0, spread]
{
cout << "{ " << lab << " " << n << " { ";
vector<int> v;
int elem = base;
for (int i = 0; i<n; ++i) { // создаем элементы
elem+= randint(spread);
v.push_back(elem);
}
int val = base + randint(elem–base); // создаем искомое значение
bool found = false;
for (int i = 0; i<n; ++i) { // печатаем элементы и проверяем,
// найден ли элемент val
if (v[i]==val) found = true;
cout << v[i] << " ";
}
cout << "} " << found << " }\n";
}
Отметим, что для проверки, найден ли элемент
val
в случайной последовательности, мы не использовали функцию binary_search
. Для того чтобы обеспечить корректность теста, мы не должны использовать функцию, которую проверяем. На самом деле функция
binary_search
не самый удобный пример для тестирования с помощью наивного подхода на основе случайных чисел. Мы сомневаемся, что сможем найти какие-то новые ошибки, пропущенные на ранних этапах с помощью тестов, разработанных “вручную”, тем не менее этот метод довольно часто оказывается полезным. В любом случае следует выполнить несколько случайных тестов.