Читаем Thinking In C++. Volume 2: Practical Programming полностью

The Test class uses RTTI[23] to get the name of your class (for example, DateTest) for the report. There is also a setStream( ) member function if you want the test results sent to a file instead of to the standard output (the default). You’ll see the Test class implementation later in this chapter.

The test_ ( ) macro can extract the text of the Boolean condition that fails, along with its file name and line number.[24] To see what happens when a failure occurs, you can introduce an intentional error in the code, say by reversing the condition in the first call to test_( ) in DateTest::testOps( ) in the previous example code. The output indicates exactly what test was in error and where it happened:.

DateTest failure: (mybday > today) , DateTest.h (line 31)

Test "DateTest":

        Passed: 20      Failed: 1

In addition to test_( ), the framework includes the functions succeed_( ) and fail_( ), for cases in which a Boolean test won't do. These functions apply when the class you’re testing might throw exceptions. During testing, you want to arrange an input set that will cause the exception to occur to make sure it’s doing its job. If it doesn’t, it’s an error, in which case you call fail_( ) explicitly to display a message and update the failure count. If it does throw the exception as expected, you call succeed_ ( ) to update the success count.

To illustrate, suppose we update the specification of the two non-default Date constructors to throw a DateError exception (a type nested inside Date and derived from std::logic_error) if the input parameters do not represent a valid date:.

Date(const string& s) throw(DateError);

Date(int year, int month, int day) throw(DateError);

The DateTest::run( ) member function can now call the following function to test the exception handling:

  void testExceptions() {

    try {

      Date d(0,0,0);  // Invalid

      fail_("Invalid date undetected in Date int ctor");

    }

    catch (Date::DateError&) {

      succeed_();

    }

    try {

      Date d("");  // Invalid

      fail_("Invalid date undetected in Date string ctor");

    }

    catch (Date::DateError&) {

      succeed_();

    }

  }

In both cases, if an exception is not thrown, it is an error. Notice that you have to manually pass a message to fail_( ), since no Boolean expression is being evaluated.

<p>Test suites</p>

Real projects usually contain many classes, so you need a way to group tests so that you can just push a single button to test the entire project.[25] The Suite class allows you to collect tests into a functional unit. You derive Test objects to a Suite with the addTest( ) member function, or you can swallow an entire existing suite with addSuite( ). We have a number of date-related classes to illustrate how to use a test suite. Here's an actual test run:.

// Illustrates a suite of related tests

#include

#include "suite.h"         // includes test.h

#include "JulianDateTest.h"

#include "JulianTimeTest.h"

#include "MonthInfoTest.h"

#include "DateTest.h"

#include "TimeTest.h"

using namespace std;

int main() {

    Suite s("Date and Time Tests");

    s.addTest(new MonthInfoTest);

    s.addTest(new JulianDateTest);

    s.addTest(new JulianTimeTest);

    s.addTest(new DateTest);

    s.addTest(new TimeTest);

    s.run();

    long nFail = s.report();

    s.free();

    return nFail;

}

/* Output:

Suite "Date and Time Tests"

===========================

Test "MonthInfoTest":

   Passed: 18  Failed: 0

Test "JulianDateTest":

   Passed: 36  Failed: 0

Test "JulianTimeTest":

   Passed: 29  Failed: 0

Test "DateTest":

   Passed: 57  Failed: 0

Test "TimeTest":

   Passed: 84  Failed: 0

===========================

*/

Each of the five test files included as headers tests a unique date component. You must give the suite a name when you create it. The Suite::run( ) member function calls Test::run( ) for each of its contained tests. Much the same thing happens for Suite::report( ), except that it is possible to send the individual test reports to a destination stream that is different from that of the suite report. If the test passed to addSuite( ) has a stream pointer assigned already, it keeps it. Otherwise, it gets its stream from the Suite object. (As with Test, there is a second argument to the suite constructor that defaults to std::cout.) The destructor for Suite does not automatically delete the contained Test pointers because they don’t have to reside on the heap; that’s the job of Suite::free( ).

<p>The test framework code</p>

The test framework code library is in a subdirectory called TestSuite in the code distribution available on the MindView website. To use it, include the search path for the TestSuite subdirectory in your header, link the object files, and include the TestSuite subdirectory in the library search path. Here is the header for Test.h:

//: TestSuite:Test.h

#ifndef TEST_H

#define TEST_H

#include

#include

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных