Скачиваний:
31
Добавлен:
01.05.2014
Размер:
66.05 Кб
Скачать

Санкт-Петербургский Государственный Электротехнический Университет «ЛЭТИ»

Качество и надежность программного обеспечения

Модульное тестирование

(Unit-test)

Выполнили: студенты гр.№2382

Кривенок Д.В.

Мельник И.В.

Шабаев Г.В.

Преподаватель: Щеголева Н.Л.

Санкт-Петербург

2007

В качестве класса для тестирования был выбран класс для нахождения и определения всевозможных URL(ссылок) в тексте – CurlParser. Данный класс предостовляет простую функциональность по находжению ссылки в тексте – он выделяет текст ссылки( строку ) и начальную и конечную позицию данной строки в общем тексте. Входными данными для класса является строка, где возможно находятся сслылки, выходнными данными является массив структур содержащих информацию о строке ссылки и ее позиций в тексте. Данный класс для обработки и анализа строки использует библиотеку boost::spirit.

Для написания теста к данному классу использовалась библиотека boost::test, которая предостовляет широкие возможности по организации тестов в простые “test cases” и “test suites” , а также позволяет контролировать их выполнение.

Данная библиотека состоит из :

  • Test Tools

  • Test Execution Monitor

  • Unit Test Framework

Код класса для тестирования:

#pragma once

#pragma warning (disable : 4512) //Can not generate assignment operator in boost librarie

#pragma warning(disable : 4267)

#include <string.h>

#include <vector>

#include <math.h>

#include <comutil.h>

#include <boost/spirit/core.hpp>

#pragma warning (default : 4512)

#pragma warning(default : 4267)

using namespace boost::spirit;

//using namespace std;

struct CUrlPosition

{

CUrlPosition (DWORD nStart = 0, DWORD nEnd = 0, std::string strUrl = "")

{

m_nStartPos = nStart;

m_nEndPos = nEnd;

m_strUrl = strUrl;

}

DWORD m_nStartPos;

DWORD m_nEndPos;

std::string m_strUrl;

};

typedef std::vector<CUrlPosition> CUrlPostionArr;

typedef std::vector<CUrlPosition> CTextPositionArr;

class PushUrlPos

{

public :

PushUrlPos ( CUrlPostionArr& PosArr

, const char* nCurrentOffset )

: m_PosArr (PosArr)

, m_nCurrentOffset(nCurrentOffset)

{

}

PushUrlPos& operator = (const PushUrlPos& );

void operator ( ) ( const char* lpcszTextStart, const char* lpcszTextEnd) const

{

try

{

CUrlPosition UrlPos;

UrlPos.m_nStartPos = (DWORD) (lpcszTextStart - m_nCurrentOffset); // Length of text in bytes

UrlPos.m_nEndPos = (DWORD) (lpcszTextEnd - m_nCurrentOffset);

UrlPos.m_strUrl.append( lpcszTextStart, 0,UrlPos.m_nEndPos - UrlPos.m_nStartPos);

m_PosArr.push_back(UrlPos);

}

catch(...)

{

// Couldn't append Url

assert(0);

}

}

private:

CUrlPostionArr& m_PosArr;

LPCSTR m_nCurrentOffset;

};

class CUrlParser : public grammar<CUrlParser>

{

public:

CUrlParser ( )

{

}

CUrlParser& operator = (const CUrlParser& ) {};

template <typename ScannerT>

struct definition

{

definition ( const CUrlParser& );

rule<ScannerT> m_UrlExp

, m_HttpPref

, m_WorldWideWeb

, m_UrlName

, m_UrlNamePart

, m_DomainName

, m_SepDot

, m_SepLine

, m_SimpleEmail

, m_EmailTo

, m_ShortUrlNamePart;

rule<ScannerT> const& start() const;

};

CUrlPostionArr& GetPositionArr ( )

{

return m_PosArr;

}

private:

CUrlPostionArr m_PosArr;

};

int GetTextSize (LPCSTR lpcszText, const LOGFONT& logFnt);

template<typename ScannerT>

CUrlParser::definition<typename ScannerT>::definition (const CUrlParser& )

{

// Creating BNF for URL

m_UrlExp = (

(

(m_HttpPref >> m_WorldWideWeb)

| m_HttpPref

| m_WorldWideWeb

| m_EmailTo

)

>> m_UrlName

>> *(m_SepDot >> m_DomainName)

>> *(m_SepLine>>m_UrlName )

>> *(m_SepDot >> m_DomainName) >>*(m_SepLine)

)

| m_SimpleEmail;

m_HttpPref = str_p("http://")|str_p("HTTP://")| str_p("Http://"); // only 3 variants HtTp - not preffix

m_WorldWideWeb = (str_p("www")|str_p("WWW"))>>m_SepDot;

m_EmailTo = (str_p("Email:") | str_p("email:")) | str_p("EMAIL:") >> *space_p ;

m_ShortUrlNamePart = +( alpha_p | digit_p | ch_p('_')|ch_p(':') | ch_p('-') | ch_p('~') | ch_p ('$')| ch_p ('&')

| ch_p('!')| ch_p('#')| ch_p('%')

| ch_p('^')| ch_p('*') | ch_p('+')| ch_p('|'));

m_UrlNamePart = +(m_ShortUrlNamePart | ch_p('@') );

m_UrlName = m_UrlNamePart ;

m_DomainName = m_UrlNamePart;

m_SepDot = ch_p ('.');

m_SepLine = ch_p('/');

m_SimpleEmail = *(m_ShortUrlNamePart) >>ch_p('@') >>m_ShortUrlNamePart>> *(m_SepDot >> m_ShortUrlNamePart);

}

template<typename ScannerT>

rule<ScannerT> const& CUrlParser::definition<typename ScannerT>::start() const

{

return m_UrlExp;

}

Код тестового модуля:

// Include BOOST Test framework

#include <boost/test/test_tools.hpp>

#include <boost/test/results_reporter.hpp>

#include <boost/test/unit_test_suite.hpp>

#include <boost/test/output_test_stream.hpp>

#include <boost/test/unit_test_log.hpp>

#include <boost/test/framework.hpp>

#include <boost/test/detail/unit_test_parameters.hpp>

#include <boost/lexical_cast.hpp>

// STL

#include <iostream>

// include class to test

#include "HyperLinkDetector.h"

// namespace usage

using boost::test_tools::output_test_stream;

using boost::unit_test::test_suite;

using namespace boost::unit_test;

using namespace boost::spirit;

/// Class which performs the testing

class CURLTest

{

typedef CUrlPostionArr::iterator UrlPosIterator;

typedef CUrlPostionArr::const_iterator UrlPosConstIterator;

public:

CURLTest()

{

}

public:

/// Test empty string as URL

void TestEmptyURL()

{

BOOST_MESSAGE("Testing NULL URL")

static const std::string emptyURL("");

InitNewInstances();

DoParse( emptyURL );

UrlPosConstIterator it = m_pPosArr->begin(), endIt = m_pPosArr->end();

// we require HERE that m_pPosArr have to be empty

BOOST_REQUIRE( it == endIt );

}

/// Test simple http adress

void TestSimpleHTTP()

{

static const std::string httpURL("Http://www.google.com");

BOOST_MESSAGE("Testing simple http link " << httpURL.c_str() );

InitNewInstances();

DoParse( httpURL );

// should be one link

BOOST_CHECK( m_pPosArr->size() >= 1 );

BOOST_REQUIRE( m_pPosArr->begin()->m_strUrl == httpURL );

}

/// Test URL's inside the text adn correct URL positions

void TestTextWithLinks()

{

static const std::string textWithURL(

"Some texts 12345656778,@#&^$#@&* $!)(@$*# $%&*@ #^ http://yandex.ru ::?/sdfsdkjfkhsdf---:::/// ftp://81.3.180.101:5555/scripts/ *#&$*#&$ "

);

BOOST_MESSAGE("Testing URL's inside text: " << textWithURL);

InitNewInstances();

DoParse( textWithURL );

BOOST_CHECK( m_pPosArr->size() >= 2 );

// first link iterator

UrlPosConstIterator it = m_pPosArr->begin();

// second link iterator

UrlPosConstIterator it2( ++it );

BOOST_MESSAGE("Test first URL pos");

BOOST_CHECK( it->m_nStartPos == 51 && it->m_nEndPos == 76 );

BOOST_MESSAGE("Test first URL contents");

BOOST_CHECK( it->m_strUrl == "http://yandex.ru" );

BOOST_MESSAGE("Test second URL pos");

BOOST_CHECK( it->m_nStartPos == 105 && it->m_nEndPos == 135 );

BOOST_MESSAGE("Test second URL contents");

BOOST_CHECK( it->m_strUrl == "ftp://81.3.180.101:5555/scripts/" );

}

void TestNotFullURLs()

{

static const std::string wronghURL(

"www://dfdfdf http:\\fsdff/dfdf httP\\dfsd.ru email:erdfs@df"

);

BOOST_MESSAGE("Testing wrong URL's" << wronghURL);

InitNewInstances();

DoParse( textWithURL );

BOOST_REQUIRE( m_pPosArr->size() == 0 );

}

protected:

void InitNewInstances()

{

BOOST_

m_pURLParser.reset( new CUrlParser() );

m_pPosArr.reset( new CUrlPostionArr() );

}

void DoParse( const std::string& strToParse )

{

parse(

strToParse.c_str(),

*((*m_pURLParser)[PushUrlPos(*m_pPosArr,strToParse.c_str())] | anychar_p)

);

}

private:

/// This is the Class to test !!!

std::auto_ptr<CUrlParser> m_pURLParser;

/// Helper member to hold parsed data

std::auto_ptr<CUrlPostionArr> m_pPosArr;

};

test_suite* Init_unit_test_suite( int = 0, char* [] = 0) {

// Create the test Suite instance

test_suite* test= BOOST_TEST_SUITE( "URL Parser test exmaple" );

// Create the instance of the test class

boost::shared_ptr<CURLTest> instancePtr( new CURLTest() );

// add test functions

test->add( BOOST_CLASS_TEST_CASE( &CURLTest::TestEmptyURL, instancePtr ) );

test->add( BOOST_CLASS_TEST_CASE( &CURLTest::TestSimpleHTTP, instancePtr ) );

test->add( BOOST_CLASS_TEST_CASE( &CURLTest::TestTextWithLinks, instancePtr ) );

test->add( BOOST_CLASS_TEST_CASE( &CURLTest::TestNotFullURLs, instancePtr ) );

return test;

}

/// main execution point

int main(int, char* [])

{

// Set the output to file and setup Test framework

#define PATTERN_FILE_NAME "result_report_test.pattern"

std::string pattern_file_name(

argc == 1 ? (runtime_config::save_pattern() ? PATTERN_FILE_NAME : "./test_files/" PATTERN_FILE_NAME )

: argv[1] );

output_test_stream test_output( pattern_file_name, !runtime_config::save_pattern() );

results_reporter::set_stream( test_output );

// Create test Suite

test_suite* pTestSuite = Init_unit_test_suite( );

// Run tests

framework::run( pTestSuite );

return 0;

}

Результаты тестирования:

Содержание выходного файла:

Test suite "URL Parser test exmaple”

9 assertions out of 9 passed

4 test cases out of 4 passed

<TestResult><TestSuite name=" URL Parser test exmaple" result="passed" assertions_passed="9" assertions_failed="0" expected_failures="1" test_cases_passed="4" test_cases_failed="0" test_cases_skipped="0"></TestSuite></TestResult>