![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Collections comparisonBoost , Boost.Test , Extended comparisons support
|
![]() |
Note |
---|---|
При этом дополнительной диагностики не предусмотрено.Единичная система испытаний. См. раздел< |
Код |
---|
<#defineBOOST_TEST_MODULEboost_test_sequence #include<boost/test/included/unit_test.hpp> #include<vector> BOOST_AUTO_TEST_CASE(test_collections_vectors) { std::vector<int>a{1,2,3},c{1,5,3,4}; std::vector<long>b{1,5,3}; // the following does not compile //BOOST_TEST(a == b); //BOOST_TEST(a <= b); // stl defaults to lexicographical comparison BOOST_TEST(a<c); BOOST_TEST(a>=c); BOOST_TEST(a!=c); }> |
выход |
---|
<>./boost_test_container_default--log_level=all Running1testcase... Enteringtestmodule"boost_test_sequence" test.cpp(13):Enteringtestcase"test_collections_vectors" test.cpp(23):info:checka<chaspassed test.cpp(24):error:in"test_collections_vectors":checka>=chasfailed test.cpp(25):info:checka!=chaspassed test.cpp(13):Leavingtestcase"test_collections_vectors";testingtime:208us Leavingtestmodule"boost_test_sequence";testingtime:286us ***1failureisdetectedinthetestmodule"boost_test_container_default"> |
Уточняя манипулятор<boost::test_tools::per_element
>, сравнение элементов контейнеров выполняетсяэлемент-мудрый, в порядке, указанном передними итераторами контейнеров. Это сравнение последовательностейэлементов, генерируемых контейнерами, для которыхUnit Test Frameworkобеспечивает расширенную диагностику.
Более подробно, пусть<c_a=(a_1,...a_n)
>и<c_b
=(b_1,...b_n)
>будут двумя последовательностями одинаковой длины, но не обязательно одного и того же типа. Эти последовательности соответствуют содержанию соответствующих контейнеров в порядке, указанном их итератором. Пусть<op
>будет одним изоператоров бинарного сравнения.
BOOST_TEST(c_a op c_b, boost::test_tools::per_element() );
является эквивалентным
if(c_a.size() == c_b.size())
{
for(int i=0; i < c_a.size(); i++)
{
BOOST_TEST_CONTEXT
("index " << i)
{
BOOST_TEST(a_i op b_i);
}
}
}
else
{
BOOST_TEST(c_a.size() == c_b.size());
}
![]() |
Warning |
---|---|
Это принципиально отличается от использования операторов сравнения контейнеров по умолчанию (поведение по умолчанию). |
![]() |
Warning |
---|---|
Это не отношения заказа на контейнеры. В качестве побочного эффекта можно BOOST_TEST(c_a == c_b) и BOOST_TEST(c_a != c_b) Неудачи одновременно |
Последовательности сравниваются с использованием указанного оператора<op
>, оцениваемого на левом и правом элементах соответствующих последовательностей. Порядок сравниваемых элементов дается итераторами соответствующих контейнеров. В случае неисправности индексы неисправных элементов<op
>возвращаются.
Код |
---|
<#defineBOOST_TEST_MODULEboost_test_sequence_per_element #include<boost/test/included/unit_test.hpp> #include<vector> #include<list> namespacett=boost::test_tools; BOOST_AUTO_TEST_CASE(test_sequence_per_element) { std::vector<int>a{1,2,3}; std::vector<long>b{1,5,3}; std::list<short>c{1,5,3,4}; BOOST_TEST(a==b,tt::per_element());// nok: a[1] != b[1] BOOST_TEST(a!=b,tt::per_element());// nok: a[0] == b[0] ... BOOST_TEST(a<=b,tt::per_element());// ok BOOST_TEST(b<c,tt::per_element());// nok: size mismatch BOOST_TEST(b>=c,tt::per_element());// nok: size mismatch BOOST_TEST(b!=c,tt::per_element());// nok: size mismatch }> |
выход |
---|
<>./boost_test_sequence_per_element Running1testcase... test.cpp(21):error:in"test_sequence_per_element":checka==bhasfailed Mismatchatposition1:2!=5. test.cpp(23):error:in"test_sequence_per_element":checka!=bhasfailed Mismatchatposition0:1==1. Mismatchatposition2:3==3. test.cpp(25):error:in"test_sequence_per_element":checkb<chasfailed Collectionssizemismatch:3!=4 test.cpp(26):error:in"test_sequence_per_element":checkb>=chasfailed Collectionssizemismatch:3!=4 test.cpp(27):error:in"test_sequence_per_element":checkb!=chasfailed Collectionssizemismatch:3!=4 ***5failuresaredetectedinthetestmodule"boost_test_sequence_per_element"> |
Для того чтобы последовательности были сопоставимы по элементам, должны выполняться следующие условия:
op
>должен быть одним из операторов сравнения<==
>,<!=
>,<<
>,<<=
>,<>
>,<>=
>a_iop
b_i
>должно быть определено, где тип<a_i
>и<b_i
>являются типом, возвращаемым оператором отсчета соответствующих коллекций.![]() |
Caution |
---|---|
Полученный тип "< BOOST_TEST(c_a == c_b == 42, boost::test_tools::per_element() ); // does not compile |
Указывая манипулятор<boost::test_tools::lexicographic
>, контейнеры сравниваются с использованиемлексикографическогопорядка и для которогосравниваются.Блок тестирования Frameworkобеспечивает дополнительную диагностику в случае отказа.
BOOST_TEST(c_a op c_b, boost::test_tools::lexicographic() );
Сравнение выполняется в порядке, указанном передовыми итераторами контейнеров.
![]() |
Tip |
---|---|
Лексикографическое сравнение дает общий порядок на контейнерах: высказывания< |
Код |
---|
<#defineBOOST_TEST_MODULEboost_test_container_lex #include<boost/test/included/unit_test.hpp> #include<vector> namespacett=boost::test_tools; BOOST_AUTO_TEST_CASE(test_collections_vectors_lex) { std::vector<int>a{1,2,3},b{1,2,2},c{1,2,3,4}; BOOST_TEST(a<a,tt::lexicographic()); BOOST_TEST(a<b,tt::lexicographic()); BOOST_TEST(a<c,tt::lexicographic()); BOOST_TEST(a>=c,tt::lexicographic()); // does not compile //BOOST_TEST(a == c, tt::lexicographic()); //BOOST_TEST(a != c, tt::lexicographic()); }> |
выход |
---|
<>./boost_test_container_lex--log_level=all Running1testcase... Enteringtestmodule"boost_test_container_lex" test.cpp(15):Enteringtestcase"test_collections_vectors_lex" test.cpp(19):error:in"test_collections_vectors_lex":checka<ahasfailed Collectionsappeartobeequal. test.cpp(20):error:in"test_collections_vectors_lex":checka<bhasfailed Failureatposition2:3>=2. test.cpp(21):info:checka<chaspassed test.cpp(22):error:in"test_collections_vectors_lex":checka>=chasfailed Secondcollectionhasextratrailingelements. test.cpp(15):Leavingtestcase"test_collections_vectors_lex";testingtime:267us Leavingtestmodule"boost_test_container_lex";testingtime:341us ***3failuresaredetectedinthetestmodule"boost_test_container_lex"> |
Как видно выше, лексикографическое сравнение является либо явным (<boost::test_tools::lexicographic()
>), либо неявным, когда контейнерные операции используют этот тип сравнения. Во втором случае, однако, невозможно воспользоваться расширенной диагностикой в случае неудачи.
Если лексикографическое сравнение является по умолчанию для конкретного контейнера, можно отправить операции сравнения в.Система испытаний блоковвместо оператора контейнеров. Для того, чтобы избежатьСтруктура модульного тестированиялексикографическое сравнение, макрос<BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE
>может использоваться следующим образом:
std::vector<int>
to lexicographic with extended diagnostic
Код |
---|
<#defineBOOST_TEST_MODULEboost_test_container_lex_default #include<boost/test/included/unit_test.hpp> #include<vector> namespacett=boost::test_tools; BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE(std::vector<int>) BOOST_AUTO_TEST_CASE(test_collections_vectors_lex) { std::vector<int>a{1,2,3},b{1,2,2}; std::vector<longint>c{1,2,3,5},d{1,2,3,4}; BOOST_TEST(a<a);// extended diagnostic BOOST_TEST(a<b);// extended diagnostic BOOST_TEST(c<d);// no extended diagnostic }> |
выход |
---|
<>./boost_test_container_lex_default Running1testcase... test.cpp:22:error:in"test_collections_vectors_lex":checka<ahasfailed. Collectionsappeartobeequal. test.cpp:23:error:in"test_collections_vectors_lex":checka<bhasfailed. Failureatposition2:3>=2. test.run-fail.cpp:24:error:in"test_collections_vectors_lex":checkc<dhasfailed ***3failuresaredetectedinthetestmodule"boost_test_container_lex_default"> |
op
>должен быть одним из упорядоченных операторов сравнения<<
>,<<=
>,<>
>,<>=
>Последовательность дается итерацией надпередним итерируемымконтейнером. Переменный контейнер - это контейнер (C++11):
size
>и<begin
>, а также поля<const_iterator
>и<value_type
>value_type
>не относится к<char
>или<wchar_t
>.С этой точки зрения, C-массивынеявляются передовыми итерируемыми контейнерами:
Код |
---|
<#defineBOOST_TEST_MODULEboost_test_container_c #include<boost/test/included/unit_test.hpp> #include<sstream> #include<map> #include<vector> BOOST_AUTO_TEST_CASE(test_collections_not_on_c_arrays) { inta[]={1,2,3}; intb[]={1,5,3,4}; BOOST_TEST(a==b); }> |
выход |
---|
<>./boost_test_macro_container_c_array--log_level=all Running1testcase... Enteringtestmodule"boost_test_container_c" test.cpp(15):Enteringtestcase"test_collections_not_on_c_arrays" test.cpp(19):error:in"test_collections_not_on_c_arrays":checka==bhasfailed[0x7fff526e5bc4!=0x7fff526e5bb0] test.cpp(15):Leavingtestcase"test_collections_not_on_c_arrays";testingtime:323us Leavingtestmodule"boost_test_container_c";testingtime:526us ***1failureisdetectedinthetestmodule"boost_test_container_c"> |
Обнаружение контейнеров делегировано классу<boost::unit_test::is_forward_iterable
>, который для C++11 обнаруживает необходимые функции и поля участника. Однако для C++03 типы, обеспечивающие последовательности, должны быть явно указаны.Единичная система испытанийпо специализации<boost::unit_test::is_forward_iterable
>.
это может быть не так, например,<std::unordered_map
>, для которых ведра могут заполняться по-разному в зависимости от порядка вставки.
в данном случае<v_a<v_b
>означает, что точка<v_a
>находится внутри прямоугольника (происхождение,<v_b
>)
Статья Collections comparison раздела Boost.Test Extended comparisons support может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Extended comparisons support ::
реклама |