Contents:
UTest is a user-friedly unit testing library based on C++11. The main purpose of this project is to provide a convenient and flexible way of writing tests and collecting information.
So here are key features of this library:
- Simple test writing with
TESTkeyword - Verification statements
ASSERTandEXPECT - Collecting data from tests
- Saving data to json (and back)
Here is a little tutorial of possible ways UTest usage, but first of all, you have to install UTest.
Use TEST keyword to declare your own test. The first argument is name of this test, the second is the name of test group. For example:
TEST(MyTestName, Common) {
// some code in test
}Test will register automatically, so that's all you need to do to create test.
Tips:
- It's more convenient to write tests for your project in different files. For example, split groups of tests into their own files. But don't forget to include tests into
main.cppwhere you can run them.
You can use ASSERT_TRUE and EXPECT_TRUE keywords ("commands" in this text) to verify some statement:
TEST(MyTestName, Common) {
ASSERT_TRUE(2 * 2 == 4)
EXPECT_TRUE(5 != 7)
}Features:
- You shouldn't put a semicolon (
;) symbol after keywords (because they are macros at real). ASSERTstatement will stop test execution in case of fail, in oppositeEXPECTwill only indicate that statement inside was wrong. So code after failedASSERTstatement will be unreachable.ASSERTstatements catch exceptions (because it stops test execution), whenEXPECTthrows exception again after it was caught.- If
EXPECTfailed it's considered that test isfailed, but in case ofASSERTfailure test becomesfatal_failed. We can see this difference inUTest::CommandStatusclass here.
When tests are done, they must be executed for getting results. Use:
UTest::ExecuteTestAll()to execute all testsUTest::ExecuteTestGroup(std::string group_name)to run all tests of particular groupUTest::ExecuteTest(std::string test_name)to execute exact test
All of these methods return UTest::TestResult class object, that you can interact to.
Log:
You should see execution log in stdout while tests execution in case UTest::IsOStreamEnabled() was true by the time the tests were run, also in stderr if UTest::IsOCerrStreamEnabled().
Yeah, execution log while testing is really comfortable for reading, but what if you need to save all you have seen? UTest will help you to solve this problem. Here are some options of tests output:
-
stdout\stderr - UTest uses
std::coutandstd::cerrfor displaying this -
UTest::TestResult - it's a flexible object that contains tests results
-
Execution status classes like:
UTest::TestGroupStatusUTest::TestStatusUTest::CommandStatus
These things are just simple data structs that will help you read information in code easily
-
.json - static storage of tests output as a file
By default UTest uses std::cout and std::cerr for displaying tests execution process. There are some options you can use to configure output:
- Stdout:
UTest::ToggleOStream()function toggles stdout outputUTest::IsOStreamEnabled()- true if stdout output enabled
- Stderr:
UTest::ToggleOCerrStream()- toggles stderr outputUTest::IsOCerrStreamEnabled()- shows is stderr output enabled
- Other:
UTest::SwitchStreams()- switches (stdout and stderr) streams by toggling stdout and stderr
Also there are a some cosmetic output settings such as:
-
Console colors configuration: here is the list of parameters you can specify to change log colors: Use
UTest::ConsoleColorsConfig::<parameter> = <value>to change configuration.common_color- color of log decoration ("blue"by default)group_passed_color- color of tests group output block if it's succeeded ("green"by default)group_failed_color- tests group block color in case of fail ("red"by default)test_start_color- color that display run of test ("blue"by default)test_passed_color- color displaying test passing ("green"by default)test_failed_color- color representing failure of test ("red"by default)command_passed_color- color of passed statement (likeASSERTorEXPECT) ("yellow"by default)command_failed_color- color of failed statement ("red"by default)command_fatal_failed_color- used for highlighting fatal failedASSERTs ("red"by default)
You can specify any of these parameters by values (colors) in list below:
"reset"- switches console color to default,"black","red","green","yellow","blue","magenta","cyan","white","brightblack","brightred","brightgreen","brightyellow","brightblue","brightmagenta","brightcyan","brightwhite"
-
Output configuration: responsible for extra information in log
-
bool is_failed_detailed- iftrueshows all verifying statements of failed tests (trueby default) -
bool is_always_detailed- make UTest output every command of every test (falseby default) -
bool is_command_failed_path_enabled- shows path to failed command (falseby default) -
bool is_test_failed_path_enabled- shows path to failed test (trueby default) -
size_t block_width- width of tests group block, should be>= 34for correct output (50by default) -
size_t stats_symbols_count- count of symbols in stats of tests group block, should be>= 10for correct output (16by default)
Use
UTest::OutputConfig::<parameter> = <value>to change these settings -
UTest::TestResult - it's a flexible object that contains info about tests execution. All the UTest::ExecuteTest[Group | All]() functions return objects of TestResult type.
TestResult is a bit smart object, it can save itself as .json file and also be constructed from it. Moreover, there is option of data auto-saving (actually, it's a serializing into file before being destructed).
Methods::
SetPathToAutoSave(const std::string& path)- sets the specified path for auto-saving ("utest_report.json"by default)ToggleAutoSave(const std::string& path = "")- toggles auto-saving into.jsonif path is not""IsAutoSaveEnabled()- returnstrueif auto-saving is enabledAddTestStatus(const TestStatus& test)- mergesTestStatus(read below) into currentTestResultobject. If test result info is already there, overwrites data with a passedTestStatus.AddGroupStatus(const TestGroupStatus& group)- mergesTestGroupStatusintoTestResultobject. Also overwrites info with a new one.SerializeToJson(std::string path = "")- saves thisTestResultas.jsonfile by passed path (if it's empty, method uses auto-save path)DeserializeFromJson(const std::string& path)- overwrites currentTestResultobject with a data from given.jsonfileGetTestGroupStatusMap()- returnsstd::unordered_map<std::string, TestGroupStatus>object that you can use for reading tests data in code easily (read below)
Also there are such secondary methods as:
- Constructors from:
const TestResult&- copy constructorconst TestGroupStatus&const TestStatus&- default constructor -> empty
TestResult
- Operators:
operator=(const TestResult& other)
These data structs have only simple public fields you can read easily in code. You can get object of status classes from UTest::TestResult by invoking it's GetTestGroupStatusMap() method (that's the only way to get it as tests execution data).
-
UTest::CommandStatus- describes one statement such asASSERTorEXPECT. Have fields:std::string type- describes what statement it isassertorexpectuint32_t line- number of line where statement is writtenstd::string arg_1- first argumentstd::string arg_2- second argumentstd::string result- result of command verifyingstd::string path- path to file where statement located
-
UTest::TestStatusstd::string name- name of this teststd::string group_name- name of it's groupuint32_t line- number of line where test is writtenstd::vector<CommandStatus> commands_history- test's commands execution historystd::chrono::duration<double> execution_time- time spent for teststd::string result- result of teststd::string path- path to file where test located
-
UTest::TestGroupStatusstd::string group_name- name this groupstd::vector<TestStatus> tests_history;- group's tests execution historystd::chrono::duration<double> group_execution_time- time spent for this tests groupstd::string result- result of this group
In these types UTest uses some standard string values (as macros) to specify results:
UTEST_KEYWORD_UNDEFINED_RESULT,UTEST_KEYWORD_TEST_START,UTEST_KEYWORD_PASSED,UTEST_KEYWORD_FAILED,UTEST_KEYWORD_EXCEPTION_FAILED,UTEST_KEYWORD_FATAL_FAILED,UTEST_KEYWORD_EXCEPTION_FATAL_FAILED
So that's all values result variables can take.
Serializing to .json format is implemented as SerializeToJson(std::string path = "") method of TestResult class. Deserialization works in a similar way via DeserializeFromJson(const std::string& path) method of the same class.
Also, in UTest there is json auto-save option. Every test you execute will be written to json after end of program automatically, you just need to...
UTest::ToggleOJsonFile(const std::string& new_path = "")- use this method to toggle json auto-outputUTest::SetOutputJsonFilePath(const std::string& new_path)- use this method to specify path where to save.jsonfile (it's"utest_report.json"by default)UTest::IsOJsonFileEnabled()- returnstrueif json auto-output is enabled
There are some examples of using UTest in examples/ folder.
example_1is about tests runningexample_2shows how to manage withTestResultobjects and save them into json (and load)example_3describes how set up auto-output and auto-saving into json
If you want to run one of them, use instruction:
- Make temp folder in UTest repository like
build/ortmp/ - Move to it using
cd tmpand run cmake:cmake -DBUILD_EXAMPLES=ON .. - Run
make - Examples are built, so u need to choose one and run via
examples/<example_name>
There are several ways you can attach UTest library to your project.
That is the fastest and easiest way to integrate UTest.
Requirements:
- No requirements
Steps:
-
Open repository of UTest (or local directory if you have it downloaded already):

-
Go to "single-include/UTest" folder and find "UTest.hpp" file:
You should see this: -
Paste this file to your project folder
-
Now you can use UTest library via
#include "UTest.hpp"in your project. (or#include <UTest.hpp>, it depends on CMake set up of your project).
Requirements:
Steps:
-
Open terminal in your local repository
-
Run
git submodule add https://gitlab.akhcheck.ru/artiom.khafizov/unittester.gitcommand - it will download UTest as submodule of your git repository. -
Open your main
CMakeLists.txtfile -
Add lines:
-
add_subdirectory(unittester) -
target_link_libraries(<your_lib/executable> UTestLibrary)like this:cmake_minimum_required(VERSION 3.10) project(Example) set(CMAKE_CXX_STANDARD 11) add_subdirectory(unittester) add_executable(example_main main.cpp) target_link_libraries(example_main UTestLibrary)
-
-
Now you can use UTest library via
#include <UTest.hpp>. For example:#include <iostream> #include <UTest.hpp> TEST(HelloWorld, Common) { std::cout << "Hello, world!\n"; } int main() { UTest::ExecuteTestAll(); return 0; }
Clone UTest repository, create some folder inside for test build, for example tmp/ or build/.
Move to this folder and run cmake -DBUILD_TESTS=ON .. and make after that. Now tests are built and you just need to use tests/tests for tests execution.
That's it! You have tested library for testing :)


