{"id":13419103,"url":"https://github.com/martinmoene/lest","last_synced_at":"2025-04-08T09:12:11.319Z","repository":{"id":37622990,"uuid":"10824044","full_name":"martinmoene/lest","owner":"martinmoene","description":"A modern, C++11-native, single-file header-only, tiny framework for unit-tests, TDD and BDD (includes C++98 variant)","archived":false,"fork":false,"pushed_at":"2025-03-18T20:04:33.000Z","size":1026,"stargazers_count":394,"open_issues_count":20,"forks_count":44,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-04-01T08:37:50.563Z","etag":null,"topics":["bdd","cast","cpp11","cpp98","header-only","no-dependencies","single-file","tdd","testing","tiny-framework"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martinmoene.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.txt","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-06-20T16:18:51.000Z","updated_at":"2025-03-26T06:44:50.000Z","dependencies_parsed_at":"2022-08-31T04:21:24.022Z","dependency_job_id":"3805a852-30ff-40c7-94e7-71817974ba4e","html_url":"https://github.com/martinmoene/lest","commit_stats":null,"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Flest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Flest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Flest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Flest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martinmoene","download_url":"https://codeload.github.com/martinmoene/lest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247809964,"owners_count":20999816,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdd","cast","cpp11","cpp98","header-only","no-dependencies","single-file","tdd","testing","tiny-framework"],"created_at":"2024-07-30T22:01:11.367Z","updated_at":"2025-04-08T09:12:11.299Z","avatar_url":"https://github.com/martinmoene.png","language":"C++","readme":"lest \u0026ndash; lest errors escape testing\n=======================================\n\n[![Language](https://img.shields.io/badge/language-C++-blue.svg)](https://isocpp.org/)  [![Standard](https://img.shields.io/badge/c%2B%2B-11-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![Standard](https://img.shields.io/badge/c%2B%2B-98-orange.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)  [![License](https://img.shields.io/badge/license-BSL-blue.svg)](https://opensource.org/licenses/BSL-1.0)  [![Build Status](https://github.com/martinmoene/lest/actions/workflows/ci.yml/badge.svg)](https://github.com/martinmoene/lest/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/3777o06o2ni5lww2/branch/master?svg=true)](https://ci.appveyor.com/project/martinmoene/lest/branch/master) [![Version](https://badge.fury.io/gh/martinmoene%2Flest.svg)](https://github.com/martinmoene/lest/releases) [![download](https://img.shields.io/badge/latest-download-blue.svg)](https://raw.githubusercontent.com/martinmoene/lest/master/include/lest/lest.hpp) [![Conan](https://img.shields.io/badge/on-conan-blue.svg)](https://bintray.com/martinmoene/testing/lest%3Atesting/_latestVersion) [![Vcpkg](https://img.shields.io/badge/on-vcpkg-blue.svg)](https://vcpkg.link/ports/lest) [![Try it online](https://img.shields.io/badge/on-wandbox-blue.svg)](https://wandbox.org/permlink/80a88nlPralvatNq)\n\nThis tiny C++11 test framework is based on ideas and examples by Kevlin Henney [1,2] and on ideas found in the CATCH test framework by Phil Nash [3].\n\nLet writing tests become irresistibly easy and attractive.\n\n**Contents**  \n- [Example usage](#example-usage)\n- [In a nutshell](#in-a-nutshell)\n- [License](#license)\n- [Dependencies](#dependencies)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Synopsis](#synopsis)\n- [Variants of *lest*](#variants-of-lest)\n- [Features of *lest*](#features-of-lest)\n- [Reported to work with](#reported-to-work-with)\n- [Building tests and examples](#building-tests-and-examples)\n- [Contributions to *lest*](#contributions-to-lest)\n- [Other test frameworks](#other-test-frameworks)\n- [Notes and references](#notes-and-references)\n\n\nExample usage\n-------------\n\n```Cpp\n#include \"lest/lest.hpp\"\n\nusing namespace std;\n\nconst lest::test specification[] =\n{\n    CASE( \"Empty string has length zero (succeed)\" )\n    {\n        EXPECT( 0 == string(  ).length() );\n        EXPECT( 0 == string(\"\").length() );\n    },\n\n    CASE( \"Text compares lexically (fail)\" )\n    {\n        EXPECT( string(\"hello\") \u003e string(\"world\") );\n    },\n\n    CASE( \"Unexpected exception is reported\" )\n    {\n        EXPECT( (throw std::runtime_error(\"surprise!\"), true) );\n    },\n\n    CASE( \"Unspecified expected exception is captured\" )\n    {\n        EXPECT_THROWS( throw std::runtime_error(\"surprise!\") );\n    },\n\n    CASE( \"Specified expected exception is captured\" )\n    {\n        EXPECT_THROWS_AS( throw std::bad_alloc(), std::bad_alloc );\n    },\n\n    CASE( \"Expected exception is reported missing\" )\n    {\n        EXPECT_THROWS( true );\n    },\n\n    CASE( \"Specific expected exception is reported missing\" )\n    {\n        EXPECT_THROWS_AS( true, std::runtime_error );\n    },\n};\n\nint main( int argc, char * argv[] )\n{\n    return lest::run( specification, argc, argv );\n}\n```\nNote: besides above table approach, *lest* also supports [auto-registration of tests](#test-case-macro).\n\n### Compile and run\n\n```\nprompt\u003eg++ -Wall -Wextra -std=c++11 -I../include -o 05_select.exe 05_select.cpp \u0026\u0026 05_select.exe\n05_select.cpp:17: failed: Text compares lexically (fail): string(\"hello\") \u003e string(\"world\") for \"hello\" \u003e \"world\"\n05_select.cpp:22: failed: got unexpected exception with message \"surprise!\": Unexpected exception is reported: (throw std::runtime_error(\"surprise!\"), true)\n05_select.cpp:37: failed: didn't get exception: Expected exception is reported missing: true\n05_select.cpp:42: failed: didn't get exception of type std::runtime_error: Specific expected exception is reported missing: true\n4 out of 7 selected tests failed.\n```\n\nWith [Buck](https://buckbuild.com/):\n```\nprompt\u003e buck run example/:05_select\n...\n```\n\n\nIn a nutshell\n-------------\n\n**lest** is a small C++11 test framework for unit testing, regression testing, [Test-driven development (TDD)](http://en.wikipedia.org/wiki/Test-driven_development) and [Behaviour-driven design (BDD)](http://dannorth.net/introducing-bdd/). It replicates innovative ideas in C++ testing from the [Catch test framework](https://github.com/philsquared/Catch) such as [function-level fixtures](#fixture-macros) and [expression-decomposing assertion macros](#assertion-macros) in a form that is compact enough to read in five minutes. The lest_cpp03 variant provides similar capabilities to use with C++98/03 compilers.\n\n**Features and properties of lest** are ease of installation (single header), no boilerplate code,  traditional unit test cases and BDD style scenarios, strings as test names, function-level fixtures, expression-decomposing assertion macros, support for floating point comparison, test selection from commandline, test duration timing, test randomisation and sorting, display of passing tests, colourised output (compile-time option), C++11 code and a C++98/03 variant with comparable features (also compilable as C++11). \n\n**Features available via other projects** are mocking (see [integrate Trompeloeil mocking framework](#main-trompeloeil)) and hamcrest matchers (see [variants of lest](#variants-of-lest)), \n\n**Not provided** are things present in [other test frameworks](#other-test-frameworks), such as suites of tests, value-parameterised tests, type-parameterised tests, test data generators, customisable reporting, easy logging of extra information, breaking into a debugger, concurrent execution of tests, isolated execution of tests, Visual Studio Test Adapter.\n\n\nLicense\n-------\n*lest* uses the [Boost Software License](LICENSE.txt).\n \n\nDependencies\n------------\n*lest* has no other dependencies than the [C++ standard library](http://en.cppreference.com/w/cpp/header).\n\n\nInstallation\n------------\n\n*lest* is a single-file header-only library. Put `lest.hpp`, or a variant of it such as `lest_cpp03.hpp` directly into the project source tree or somewhere reachable from your project.\n\n\nUsage\n--------\n- [Making a case](#test-case-macro) \u0026ndash; [example](example/05-select.cpp#L9)\n- [Asserting for success](#assertion-macros) \u0026ndash; [example](example/05-select.cpp#L11)\n- [Asserting for failure](#assertion-macros) \u0026ndash; [example](example/05-select.cpp#L13)\n- [Asserting for exceptions](#assertion-macros) \u0026ndash; [example](example/05-select.cpp#L28)\n- [Asserting for a specific exception](#assertion-macros) \u0026ndash; [example](example/05-select.cpp#L33)\n- [Comparing floating point numbers](#floating-point-comparison) \u0026ndash; [example](example/06-approx.cpp).\n- [Auto test registration](#test-case-macro) \u0026ndash; [single-file example](example/11-auto-reg.cpp)\n- [Auto test registration with multiple source files](#test-case-macro) \u0026ndash; [example part  1](example/13-module-auto-reg-1.cpp), [2](example/13-module-auto-reg-2.cpp), [3](example/13-module-auto-reg-3.cpp). \n- [Non-auto test registration](#test-case-macro) \u0026ndash; [single-file example](example/05-select.cpp) \n- [Non-auto test registration with multiple source files](#module-registration-macro) \u0026ndash; [example part 1](example/12-module-1.cpp), [2](example/12-module-2.cpp), [3](example/12-module-3.cpp).\n- [Using fixtures](#fixture-macros) \u0026ndash; [example](example/09-fixture.cpp).\n- [Using *lest* assertions in a (reusable) user-defined function or lambda](#tests) \u0026ndash; [function](example/15-extract-function.cpp), [templated function](example/15-extract-template-function.cpp), [lambda](example/15-extract-lambda.cpp).\n- [Writing the test main function](#main) \u0026ndash; [single-file auto](example/11-auto-reg.cpp), [non-auto](example/05-select.cpp) \u0026ndash; [multi-file auto part 1](example/13-module-auto-reg-1.cpp), [2](example/13-module-auto-reg-2.cpp), [3](example/13-module-auto-reg-3.cpp), [non-auto part 1](example/12-module-1.cpp), [2](example/12-module-2.cpp), [3](example/12-module-3.cpp).\n- [Integrating *lest* with the Trompeloeil mocking framework](#main-trompeloeil) \u0026ndash; [example](example/16-trompeloeil-runtime.cpp).\n- [Reporting a user-defined type](#reporting-a-user-defined-type) \u0026ndash; [example](example/07-udt.cpp).\n- [Running tests](#command-line)\n\n\nSynopsis\n--------\n\n**Contents**  \n- [Command line](#command-line)\n- [Test case macro](#test-case-macro)\n- [Fixture macros](#fixture-macros)\n- [Assertion macros](#assertion-macros)\n- [BDD style macros](#bdd-style-macros)\n- [Module registration macro](#module-registration-macro)\n- [Feature selection macros](#feature-selection-macros)\n- [Standard selection macro](#standard-selection-macro)\n- [Namespace](#namespace)\n- [Tests](#tests)\n- [Main](#main)\n- [Main (Trompeloeil)](#main-trompeloeil)\n- [Floating point comparison](#floating-point-comparison)\n- [Reporting a user-defined type](#reporting-a-user-defined-type)\n\n### Command line\nUsage: **test** [options] [_test-spec_ ...]  \n\nOptions:\n- `-h, --help`, this help message\n- `-a, --abort`, abort at first failure\n- `-c, --count`, count selected tests\n- `-g, --list-tags`, list tags of selected tests\n- `-l, --list-tests`, list selected tests\n- `-p, --pass`, also report passing tests\n- `-z, --pass-zen`, ... without expansion\n- `-t, --time`, list duration of selected tests\n- `-v, --verbose`, also report passing or failing sections\n- `--order=declared`, use source code test order (default)\n- `--order=lexical`, use lexical sort test order\n- `--order=random`, use random test order\n- `--random-seed=n`, use *n* for random generator seed\n- `--random-seed=time`, use time for random generator seed\n- `--repeat=n`, repeat selected tests *n* times (-1: indefinite)\n- `--version`, report lest version and compiler used\n- `--`, end options\n\nTest specification:\n- `\"@\"`, `\"*\"`: all tests, unless excluded\n- _empty_: all tests, unless tagged [hide] or [.*optional-name*]\n- `\"text\"`: select tests that contain _text_ (case insensitive)\n- `\"!text\"`: omit tests that contain _text_ (case insensitive)\n\nTest descriptions can contain tags such as `[option]`, `[hide]` and `[.integration]`. Tests that contain the tag `[hide]` or a tag that starts with `[.` in their description are skipped, unless they are specifically selected by specifying `\"@\"`, `\"*\"`, or by specifying (part of) the tag.\n\nTest specifications can be combined and are evaluated left-to-right. For example: `a !ab abc` selects all tests that contain 'a', except those that contain 'ab', but include those that contain 'abc'.\n\nWhen regular expression selection has been enabled (and works), test specifications can use the regular expression syntax of `std::regex_search()`. See also `lest_FEATURE_REGEX_SEARCH` in section [Other Macros](#other-macros).\n\n### Test case macro\nA *lest* test specification can consist of a) one or more arrays of test cases that use lambdas, or b) auto-registered test cases that use free functions. See also macro [lest_FEATURE_AUTO_REGISTER](#other-macros). \n\n**CASE(** \"_proposition_\" **) {** _code_ **}** \u0026emsp; *(array of cases)*  \nDescribe the expected behaviour to test for and specify the actions and expectations. See also section [Module registration macro](#module-registration-macro) \u0026ndash; [Single-file code example](example/02-basic.cpp) \u0026ndash; [Multi-file code example part 1](example/12-module-1.cpp), [2](example/12-module-2.cpp), [3](example/12-module-3.cpp).\n\n**CASE_ON(** \"_proposition_\", ...**) {** _code_ **}** \u0026emsp; *(array of cases, since v1.33)*  \nDescribe the expected behaviour to test for and specify the actions and expectations. After the description you can add a lambda capture list to refer to symbols in the enclosing scope. See also section [Module registration macro](#module-registration-macro) \u0026ndash; [Single-file code example](example/02-basic.cpp) \u0026ndash; [Multi-file code example part 1](example/12-module-1.cpp), [2](example/12-module-2.cpp), [3](example/12-module-3.cpp).\n\n**lest_CASE(** _specification_, \"_proposition_\" **) {** _code_ **}** \u0026emsp; *(auto-registered cases)*  \nProvide the collection of test cases, describe the expected behaviour to test for and specify the actions and expectations. Consider defining macro CASE(_proposition_) to hide the collection of test cases and define it in terms of lest_CASE(...) \u0026ndash; [Single-file code example](example/11-auto-reg.cpp)  \u0026ndash; [Multi-file code example part  1](example/13-module-auto-reg-1.cpp), [2](example/13-module-auto-reg-2.cpp), [3](example/13-module-auto-reg-3.cpp). \n\n### Fixture macros\n*lest* provides function-level fixtures. Fixtures are stack-based and their setup and teardown occurs at the block scope of SETUP and (nested) SECTIONs \u0026ndash; [Code example](example/09-fixture.cpp).\n\n**SETUP(** \"_context_\" **) {** _code_ **}**  \nDescribe and setup the context to use afresh in each enclosed section. \n\n**SECTION(** \"_proposition_\" **) {** _code_ **}**  \nDescribe the expected behaviour to test for using the enclosing context and specify the actions and expectations. The objects in the enclosing setup or section come into existence and go out of scope for each section. A section must be enclosed in setup or in another section. \n\n### Assertion macros\n*lest* has expression-decomposing assertion macros. An expression with strings such as `hello \u003e world` may be reported with code and expansion as `hello \u003e world (\"hello\" \u003e \"world\")`. As a consequence, only a few assertion macro variants are needed \u0026ndash; [Code example](example/05-select.cpp).\n\n**EXPECT(** _expr_ **)**  \nEvaluate the expression and report failure. If an exception is thrown it is caught, reported and counted as a failure.\n\n**EXPECT_NOT(** _expr_ **)**  \nEvaluate the expression, record the *logical not* of its result and report failure. If an exception is thrown it is caught, reported and counted as a failure. This macro is a workaround to circumvent ! prefixed expressions as these cannot be decomposed.\n\n**EXPECT_NO_THROW(** _expr_ **)**  \nExpect that no exception (of any type) is thrown during evaluation of the expression.\n\n**EXPECT_THROWS(** _expr_ **)**  \nExpect that an exception (of any type) is thrown during evaluation of the expression.\n\n**EXPECT_THROWS_AS(** _expr_, _exception_ **)**  \nExpect that an exception of the specified type is thrown during evaluation of the expression.\n\nIf an assertion fails, the remainder of the test that assertion is part of is skipped.\n\n### BDD style macros\n*lest* provides several macros to write [Behaviour-Driven Design (BDD)](http://dannorth.net/introducing-bdd/) style scenarios \u0026ndash; [Code example](example/10-bdd.cpp), [auto-registration](example/10-bdd-auto.cpp).\n\n**lest_SCENARIO(** _specification_, \"_sketch_\" **) {** _code_ **}** \u0026emsp; *(auto-registered cases)*     \n\n**SCENARIO(** \"_sketch_\" **) {** _code_ **}** \u0026emsp; *(array of cases)*  \n\n**GIVEN(** \"_context_\" **) {** _code_ **}**  \n\n**WHEN(** \"_action_\" **) {** _code_ **}**  \n\n**THEN(** \"_result_\" **) {** _code_ **}**  \n\n**AND_WHEN(** \"_action_\" **) {** _code_ **}**  \n\n**AND_THEN(** \"_result_\" **) {** _code_ **}**  \n\nThese macros simply map to macros CASE(), SETUP() and SECTION().\n\nFor auto-registered scenarios, consider defining macro SCENARIO(proposition) to hide the collection of scenarios and define it in terms of lest_SCENARIO(...).\n\n### Module registration macro\nWhen using *arrays of  test cases* written across multiple files, you can use macro MODULE() to add a module's test cases to the overall specification \u0026ndash; [Code example part 1](example/12-module-1.cpp), [2](example/12-module-2.cpp), [3](example/12-module-3.cpp).\n\n**MODULE(** _overall-specification_, _module-specification_ **)**  \nRegister this module's test specification with the overall specification.\n\nNote that with *lest* using [auto test case registration](#other-macros) there's no need for macro MODULE(), see the [auto-registration example part  1](example/13-module-auto-reg-1.cpp), [2](example/13-module-auto-reg-2.cpp), [3](example/13-module-auto-reg-3.cpp). The same holds for *lest_cpp03*, see [cpp03 example part 1](example/14-module-cpp03-1.cpp), [2](example/14-module-cpp03-2.cpp), [3](example/14-module-cpp03-3.cpp).\n\n### Feature selection macros\n-D\u003cb\u003elest_NO_SHORT_MACRO_NAMES\u003c/b\u003e  \n-D\u003cb\u003elest_NO_SHORT_ASSERTION_NAMES\u003c/b\u003e (deprecated)  \nAll public API macros of _lest_ exist as lest\\_*MACRO* and shorthand _MACRO_ variant. Define this macro to omit the shorthand macros.\n\n-D\u003cb\u003elest_FEATURE_AUTO_REGISTER\u003c/b\u003e=0  \nDefine this to 1 to enable auto registration of test cases.  Default is 0.\n\nSee also section [Test case macro](#test-case-macro).\n\n-D\u003cb\u003elest_FEATURE_COLOURISE\u003c/b\u003e=0  \nDefine this to 1 to emphasise success and failure with colour. Default is 0.\n\nNote: [ANSI colour codes](http://en.wikipedia.org/wiki/ANSI_escape_code) are used. On Windows versions that [lack support for this](http://stackoverflow.com/questions/16755142/how-to-make-win32-console-recognize-ansi-vt100-escape-sequences) you can use the [ANSICON](https://github.com/adoxa/ansicon) terminal. Executables can be obtained [here](http://ansicon.adoxa.vze.com/).\n\n-D\u003cb\u003elest_FEATURE_LITERAL_SUFFIX\u003c/b\u003e=0  \nDefine this to 1 to append `u`, `l`, a combination of these, or `f` to numeric literals. Default is 0.\n\n-D\u003cb\u003elest_FEATURE_REGEX_SEARCH\u003c/b\u003e=0  \nDefine this to 1 to enable regular expressions to select tests. Default is 0.\n\nNote: You have to make sure the compiler's library has a working `std::regex_search()`; not all do currently. GCC 4.8.1's regex search function doesn't work yet. Visual C++ probably has a working regex search function since VC9, Visual Studio 2008 (tested VC10, Visual Studio 2010).\n\n-D\u003cb\u003elest_FEATURE_TIME_PRECISION\u003c/b\u003e=0  \nDefine this to set the precision of the duration in ms reported with option --time. Default is 0.\n\n-D\u003cb\u003elest_FEATURE_WSTRING\u003c/b\u003e=1  \nDefine this to 0 to remove references to std::wstring. Default is 1.\n\n-D\u003cb\u003elest_FEATURE_RTTI\u003c/b\u003e (undefined)  \n*lest* tries to determine if RTTI is available itself. If that doesn't work out, define this to 1 or 0 to include or remove uses of RTTI (currently a single occurrence of `typeid` used for reporting a type name). Default is undefined.\n\n### Standard selection macro\n-D\u003cb\u003elest_CPLUSPLUS\u003c/b\u003e=199711L  \nDefine this macro to override the auto-detection of the supported C++ standard, or if your compiler does not set the `__cplusplus` macro correctly.\n\n### Namespace\nnamespace **lest** { }  \nTypes and functions are located in namespace lest.\n\n### Tests\nstruct **env** { };  \n\nstruct **test**  \n{  \n\u0026emsp;std::string name;  \n\u0026emsp;std::function\\\u003cvoid( env \u0026 )\\\u003e behaviour;  \n};\n\nYou'll need type `env` and variable `lest_env` when you have a test case that calls a user-defined function or lambda that uses lest assertions like `EXPECT()` \u0026ndash; [Call reusable function](example/15-extract-function.cpp), [Call reusable templated function](example/15-extract-template-function.cpp), and [Call reusable lambda](example/15-extract-lambda.cpp).\n\n### Main\nA typical `main()` function for *lest* may look as follows:\n```Cpp\n#include \"lest/lest.hpp\"\n\nconst lest::test specification[] = { CASE(\"...\"){} };\n\nint main( int argc, char *argv[] )\n{\n    if ( int failures = lest::run( specification, argc, argv ) )\n        return failures;\n    \n    return std::cout \u003c\u003c \"All tests passed\\n\", EXIT_SUCCESS;\n}\n```\n\nCompile and run:\n```\nprompt\u003eg++ -std=c++11 -o main.exe -I../include main.cpp \u0026\u0026 main.exe\nAll tests passed\n```\n\nOr, if feedback on success is moved to the command line:\n```Cpp\n#include \"lest/lest.hpp\"\n\nconst lest::test specification[] = { CASE(\"...\"){} };\n\nint main( int argc, char *argv[] )\n{\n    return lest::run( specification, argc, argv );\n}\n```\n\nCompile and run with feedback on success:\n```\nprompt\u003eg++ -std=c++11 -o main.exe -I../include main.cpp \u0026\u0026 main.exe \u0026\u0026 echo All tests passed\nAll tests passed\n```\n\nYou can use the following variants of *lest*'s `run()` function in main.\n\ninline  \nint **run(** std::vector\\\u003ctest\\\u003e _specification_, std::vector\\\u003cstd::string\\\u003e _arguments_, std::ostream \u0026 _os_ = std::cout );\n\ninline  \nint **run(** std::vector\\\u003ctest\\\u003e _specification_, int _argc_, char \\* _argv_[], std::ostream \u0026 _os_ = std::cout );\n\n\ntemplate\\\u003cstd::size_t N\\\u003e  \nint **run(** test const (\u0026 _specification_ )[N], std::ostream \u0026 _os_ = std::cout **)**;\n\ntemplate\\\u003cstd::size_t N\\\u003e  \nint **run(** test const (\u0026 _specification_ )[N], std::vector\\\u003cstd::string\\\u003e _arguments_, std::ostream \u0026 _os_ = std::cout **)**;\n\ntemplate\\\u003cstd::size_t N\\\u003e  \nint **run(** test const (\u0026 _specification_ )[N], int _argc_, char \\* _argv_[], std::ostream \u0026 _os_ = std::cout **)**;\n\n- _specification_ - collection of tests\n- _arguments_ - options and arguments to select and omit tests\n- _argc_, _arcv_ - options and arguments to select and omit tests\n- _os_ - stream to report to\n- returns number of failing tests\n\n### Main (Trompeloeil)\n\nYou can integrate the [Trompeloeil mocking framework](https://github.com/rollbear/trompeloeil) with *lest* by providing a reporter for Trompeloeil \u0026ndash; [Code example](example/16-trompeloeil-runtime.cpp).\n\n```Cpp\n#include \"lest/lest.hpp\"\n#include \"trompeloeil.hpp\"\n\nint main( int argc, char * argv[] )\n{\n    std::ostream \u0026 stream = std::cout;\n    \n    trompeloeil::set_reporter(\n        [\u0026stream]( trompeloeil::severity severity, const char * file, unsigned long line, std::string const \u0026 msg )\n    {\n        if ( severity == trompeloeil::severity::fatal )\n        {\n            throw lest::message{\"\", lest::location{ line ? file : \"[file/line unavailable]\", int(line) }, \"\", msg };\n        }\n        else\n        {   \n            stream \u003c\u003c lest::location{ line ? file : \"[file/line unavailable]\", int(line) } \u003c\u003c \": \" \u003c\u003c msg;\n        }\n    });\n\n    return lest::run( specification, argc, argv, stream );\n}\n```\n\n### Floating point comparison\n*lest* provides `class approx` to compare floating point values \u0026ndash; [Code example](example/06-approx.cpp).\n\nclass **approx** { };  \n\nUse `approx` as follows:\n\nEXPECT( 1.23 == approx( 1.23 ) );  \nEXPECT( 1.23 != approx( 1.24 ) );  \n\nEXPECT( 1.23 != approx( 1.231 ) );  \nEXPECT( 1.23 == approx( 1.231 ).epsilon( 0.1 ) );  \n\napprox custom = approx::custom().epsilon( 0.1 );  \n    \nEXPECT( approx( 1.231 ) != 1.23 );  \nEXPECT( custom( 1.231 ) == 1.23 );  \n\nClass `approx` also provides *less-than or equal* and *greater-than or equal* operators.\n\n### Reporting a user-defined type\n*lest* allows you to report a user-defined type via operator\u003c\u003c() \u0026ndash; [Code example](example/07-udt.cpp).\n\nTo report a type not yet supported by *lest*, define a streaming function for it:  \n\nnamespace ns {  \n\u0026emsp;struct _user-defined-type_ { ... };  \n\u0026emsp;std::ostream \u0026 **operator\u003c\u003c** ( std::ostream \u0026 os, _user-defined-type_ const \u0026 _type_ )  \n\u0026emsp;{  \n\u0026emsp;\u0026emsp;using lest::to_string;  \n\u0026emsp;\u0026emsp;return os \u003c\u003c ... ;  \n\u0026emsp;}  \n}\n\nIn it, stream the constituent parts of the type via lest's `to_string()` conversion functions.\n\n\nVariants of *lest*\n------------------\n\nVarious variants of *lest* are kept here. The simple ones, such as `lest_basic` and `lest_decompose` provide an easy read into the techniques used and remain the tiny test frameworks that are a good fit to include with small projects.\n\nYou are encouraged to take it from here and change and expand it as you see fit and publish your variant. If you do, I'd much appreciate to hear from you!\n\n- lest.hpp - lest's latest development, this project.\n- lest_basic.hpp - lest at its very basic, this project.\n- lest_decompose.hpp - lest with expression decomposition, this project.\n- lest_cpp03.hpp - lest with expression decomposition for C++03, this project.\n- [hamlest](https://github.com/martinmoene/hamlest) - matchers for lest.\n- [lest with groups](https://github.com/pmed/lest/tree/test_group) - Pavel Medvedev\n\n\nFeatures of *lest*\n------------------\n\nFeature / variant             | latest  | cpp03  | decompose  | basic    |\n------------------------------|:-------:|:-------:|:--------:|:--------:|\nAssert expressions            | \u0026#10003;| \u0026#10003;| \u0026#10003; | \u0026#10003; |\nAssert exceptions             | \u0026#10003;| \u0026#10003;| \u0026#10003; | \u0026#10003; |\nAssert abortion (death)       | [contrib](contrib/lest_expect_abort/)  | [contrib](contrib/lest_expect_abort/)  | - | - |\nAssert assertions (death)     | [contrib](contrib/lest_expect_assert/) | [contrib](contrib/lest_expect_assert/) | - | - |\nExpression decomposition      | \u0026#10003;| modest  | modest    | -     |\nLiteral suffix u, l, f        | \u0026#10003;| -       | -         | -     |\nColourised output             | \u0026#10003;| \u0026#10003;| -         | -     |\nBDD style scenarios           | \u0026#10003;| \u0026#10003;| -         | -     |\nFixtures (sections)           | \u0026#10003;| \u0026#10003;| -         | -     |\nFloating point comparison, approx|\u0026#10003;| \u0026#10003;| -       | -     |\nFloating point comparison, ulp| -       | -       | -         | -     |\nTest selection (include/omit) | \u0026#10003;| \u0026#10003;| -         | -     |\nTest selection (regexp)       | \u0026#10003;| \u0026#10003;| -         | -     |\nHelp screen                   | \u0026#10003;| \u0026#10003;| -         | -     |\nAbort at first failure        | \u0026#10003;| \u0026#10003;| -         | -     |\nCount selected tests          | \u0026#10003;| \u0026#10003;| -         | -     |\nList tags of selected tests   | \u0026#10003;| \u0026#10003;| -         | -     |\nList selected tests           | \u0026#10003;| \u0026#10003;| -         | -     |\nReport passing tests          | \u0026#10003;| \u0026#10003;| -         | -     |\nTime duration of tests        | \u0026#10003;| \u0026#10003;| -         | -     |\nControl order of tests        | \u0026#10003;| \u0026#10003;| -         | -     |\nRepeat tests                  | \u0026#10003;| \u0026#10003;| -         | -     |\nAuto registration of tests    | \u0026#10003;| \u0026#10003;| -         | -     |\nModules of tests              | \u0026#10003;| \u0026#10003;| -         | -     |\n\u0026nbsp;                        | \u0026nbsp;  | \u0026nbsp;  |\u0026nbsp;     |\u0026nbsp; |\nSuites of tests               | -       | -       | -         | -     |\nValue-parameterised tests     | -       | -       | -         | -     |\nType-parameterised tests      | -       | -       | -         | -     |\nTest data generators          | -       | -       | -         | -     |\n[Hamcrest matchers](#variants-of-lest)| +/-| -    | -         | -     |\nMocking support               | -       | -       | -         | -     |\nLogging facility              | -       | -       | -         | -     |\nBreak into debugger           | -       | -       | -         | -     |\nConcurrent execution of tests | -       | -       | -         | -     |\nIsolated execution of tests   | -       | -       | -         | -     |\n\n\nReported to work with\n---------------------\n\nThe table below mentions the lowest version of a compiler `lest` is reported to work with.\n \nVariant / compiler     | clang | GCC   | VC    |\n-----------------------|-------|-------|-------|\nlest (latest)          |  3.2  | 4.8.1 | 12    |\nlest_basic             |  3.2  | 4.6   | 12    |\nlest_decompose         |  3.2  | 4.6   | 12    |\nlest_cpp03 (decompose) |  ?    | ?     | 8     |\n\n**Note**: I've made a few concessions to enable compilation of `lest.hpp` with Visual C++:\n- Prevent [error C2797](https://connect.microsoft.com/VisualStudio/feedbackdetail/view/917150): replace braced member initialisation with C++98 style initialisation.\n- Prevent [error C2144](https://connect.microsoft.com/VisualStudio/feedbackdetail/view/812488): use `enum{ value }` instead of `static constexpr bool` in struct `is_container` (for VC only).\n\n\nBuilding tests and examples\n---------------------------\nTests and examples can be build with Buck, via Makefiles or by using CMake.\n\nTo build the tests and examples as described below you need:\n\n- [Buck](https://buckbuild.com/) or [CMake](http://cmake.org) version 3.5 or later to be installed and in your PATH.\n- A [suitable compiler](#reported-to-work-with). \n\nThe following steps assume that the [*lest* source code](https://github.com/martinmoene/lest) has been cloned into a directory named `lest`.\n\n### Buck\n\n```\nlest\u003e buck run test:test_lest_basic\nlest\u003e buck run test:test_lest_cpp03\nlest\u003e buck run test:test_lest_decompose\nlest\u003e buck run test:test_lest\n```\n\n### CMake\n\n1. Create a directory for the build outputs for a particular architecture.  \nHere we use lest/build.\n\n        lest\u003e mkdir build \u0026\u0026 cd build\n\n2. Configure CMake to use the compiler of your choice (run `cmake --help` for a list) and build the tests for *lest* and the examples.\n\n        lest/build\u003e cmake -G \"Unix Makefiles\" [see 3. below] ..\n\n3. Optional. You can control above configuration through the following options:\n\t- `-DLEST_BUILD_TEST=ON`: build the tests for lest, default on\n\t- `-DLEST_BUILD_EXAMPLE=ON`: build the examples, default on\n\t- `-DLEST_BUILD_CONTRIB=OFF`: build the contrib folder, default off\n\t- `-DLEST_EXTRA_WARNINGS=OFF`: build with extra warnings and warnings as errors, default off\n\n4. Build the test suite.    \n\n        lest/build\u003e cmake --build .\n\n5. Run the test suite.    \n\n        lest/build\u003e ctest -V\n\nAll tests should pass, indicating your platform is supported and you are ready to use *lest*. Note that quite some examples fail. They do so to demonstrate the usage of things.\n\n\nContributions to *lest*\n-----------------------\nFolder [contrib](contrib) contains extensions to *lest*. These extensions are not part of *lest* itself because for example they use non-standard behaviour, they  are considered to be for a too-specific use case, or they are considered not yet ripe for inclusion in *lest* and we first like to gain more experience with them. \n\n\nOther test frameworks\n---------------------\nThis [comparison of Catch, doctest and lest](https://github.com/martinmoene/catch-lest-other-comparison#catchdoctestlest-feature-comparison) in table form may help you to discover similarities and differences of these frameworks.\n\n- [Catch](https://github.com/philsquared/Catch) - A modern, C++-native, header-only, framework for unit-tests, TDD and BDD.\n- [doctest](https://github.com/onqtam/doctest) - The lightest feature-rich C++ single-header testing framework for unit tests and TDD. Catch/lest-inspired tests that accompany code.\n- [snitch](https://github.com/snitch-org/snitch) - Lightweight C++20 testing framework.\n- [stf](https://github.com/jfalcou/stf) - Simple TDD Framework. Catch/lest-inspired with an emphasis on floating point precision testing.  \n- [cute](https://github.com/Kosta-Github/cute) - C++ unit test executor.\n- [bandit](http://banditcpp.github.io/bandit/) - Human friendly unit testing for C++11.\n- [igloo](http://igloo-testing.org/) - BDD style unit testing for C++.\n- [mettle](https://github.com/jimporter/mettle) - A C++14 unit test framework.\n- [CppUTest](http://cpputest.github.io/) - Unit testing and mocking framework for C/C++.\n- [UnitTest++](https://github.com/unittest-cpp/unittest-cpp) - A lightweight unit testing framework for C++.\n- [xUnit++](https://bitbucket.org/moswald/xunit/wiki/Home) - A unit testing platform for C++ inspired by [xUnit.net](http://xunit.github.io/).\n- [ZenUnit](https://github.com/NeilJustice/ZenUnit) - Single-header C++ unit testing framework for value- and type-parameterized tests.\n- [Search for C++98 test frameworks on GitHub](https://github.com/search?q=language%3AC%2B%2B+98+test+framework\u0026type=Repositories\u0026ref=advsearch)\n- [Search for C++11 test frameworks on GitHub](https://github.com/search?q=language%3AC%2B%2B+11+test+framework\u0026type=Repositories\u0026ref=advsearch)\n- [Search for C++14 test frameworks on GitHub](https://github.com/search?q=language%3AC%2B%2B+14+test+framework\u0026type=Repositories\u0026ref=advsearch)\n- [Search for C++17 test frameworks on GitHub](https://github.com/search?q=language%3AC%2B%2B+17+test+framework\u0026type=Repositories\u0026ref=advsearch)\n- [Search for C++20 test frameworks on GitHub](https://github.com/search?q=language%3AC%2B%2B+20+test+framework\u0026type=Repositories\u0026ref=advsearch)\n- [List of C++ unit testing frameworks](http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B) at Wikipedia.\n\n\nNotes and references\n--------------------\n\n[1] [Kevlin Henney on Rethinking Unit Testing in C++](http://accu.org/index.php/accu_branches/accu_london/accu_london_may_2010)  ([Video](http://skillsmatter.com/podcast/agile-testing/kevlin-henney-rethinking-unit-testing-in-c-plus-plus)).\n\n[2] Martin Moene. [Elefant C++11 test setup](http://lists.accu.org/mailman/private/accu-general/2013-June/040594.html) on the [ACCU](http://accu.org/) mailing list accu-general (requires login). It mentions the C++11 test appoach Andrzej Krzemie\u0026#x144;ski uses for [Optional. A library for optional (nullable) objects for C++11](https://github.com/akrzemi1/Optional/).\n\n[3] Phil Nash. [CATCH, an automated test framework for C, C++ and Objective-C](http://builds.catch-lib.net/).\n\n[4] A more technically informed name: lest - lambda engaged small tester.\n","funding_links":[],"categories":["TODO scan for Android support in followings","Testing Frameworks","C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinmoene%2Flest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartinmoene%2Flest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinmoene%2Flest/lists"}