Below is the quoted text from the link at the time of writing this answer (in case the web page is moved or something)
Native Tester/Compilation
As of v1.5.0 native compilation can be
performed and a new set of libraries to facilitate native testing and
native "scratch pad" compilation. eosio-cc\cpp
and eosio-ld
now
support building "smart contracts" and unit tests natively for quick
tests to help facilitate faster development (note the default
implementations of eosio intrinsics
are currently asserts that state
they are unavailable, these are user definable.)
Getting Started Once you have your smart contract written then a test
source file can be written.
hello.hpp
#include <eosiolib/eosio.hpp>
using namespace eosio;
CONTRACT hello : public eosio::contract { public:
using contract::contract;
ACTION hi( name user );
// accessor for external contracts to easily send inline actions to your contract
using hi_action = action_wrapper<"hi"_n, &hello::hi>; };
and then a quick test hello_test.cpp
#include <eosiolib/eosio.hpp>
#include <eosio/native/tester.hpp>
#include <hello.hpp>
using namespace eosio; using namespace eosio::native;
EOSIO_TEST_BEGIN(hello_test) // These can be redefined by the user
to suit there needs per unit test // the idea is that in a future
release we will have a base library that // initializes these to
"useable" default implementations and probably // helpers to more
easily define read_action_data and action_data_size intrinsics //
like these"
intrinsics::set_intrinsic<intrinsics::read_action_data>(
[](void* m, uint32_t len) {
check(len <= sizeof(eosio::name), "failed from read_action_data");
*((eosio::name*)m) = "hello"_n;
return len;
});
intrinsics::set_intrinsic<intrinsics::action_data_size>(
[]() {
return (uint32_t)sizeof(eosio::name);
});
intrinsics::set_intrinsic<intrinsics::require_auth>(
[](capi_name nm) {
});
// "Name : hello" should be in the print buffer
CHECK_PRINT("Name : hello",
[]() {
apply("test"_n.value, "test"_n.value, "hi"_n.value);
});
// should not assert apply("test"_n.value, "test"_n.value,
"check"_n.value);
name nm = "null"_n;
intrinsics::set_intrinsic<intrinsics::read_action_data>(
[&](void* m, uint32_t len) {
check(len <= sizeof(eosio::name), "failed from read_action_data");
*((eosio::name*)m) = nm;
return len;
});
REQUIRE_ASSERT( "check name not equal to `hello`",
[]() {
// should assert
apply("test"_n.value, "test"_n.value, "check"_n.value);
});
EOSIO_TEST_END
// boilerplate main, this will be generated in a future release int
main(int argc, char** argv) { silence_output(true);
EOSIO_TEST(hello_test); return has_failed(); }
Every intrinsic
that
is defined for eosio (prints, require_auth, etc.) is redefinable
given the
intrinsics::set_intrinsics<intrinsics::the_intrinsic_name>()
functions. These take a lambda whose arguments and return type should
match that of the intrinsic
you are trying to define. This gives the
contract writer the flexibility to modify behavior to suit the unit
test being written. A sister function
intrinsics::get_intrinsics<intrinsics::the_intrinsic_name>()
will
return the function object that currently defines the behavior for
said intrinsic. This pattern can be used to mock functionality and
allow for easier testing of smart contracts. For more information
please see, either the ./tests directory or
./examples/hello/tests/hello_test.cpp for working examples.
Compiling Native Code
- Raw
eosio-cpp
to compile the test or program the only addition needed to the command line is to add the flag -fnative
this will
then generate native code instead of wasm code.
- Via CMake: add_native_library and add_native_executable CMake macros have been added (these are a drop in replacement for
add_library and add_executable).
Eosio.CDT Native Tester API
CHECK_ASSERT(...)
: This macro will check whether a particular
assert has occured and flag the tests as failed but allow the rest of
the tests to run. This is called either by
CHECK_ASSERT("<assert message>", [](<args>){ whatever_function(<args>); })
CHECK_ASSERT([](std::string msg){ user defined comparison function }, [](<args>){ whatever_function(<args>); })
CHECK_PRINT(...)
: This macro will check whether the print buffer
holds the string that is expected and flag the tests as failed but
allow the rest of the test to run. This is called either by
CHECK_PRINT("<print message>", [](<args>){ whatever_function(<args>); })
CHECK_PRINT([](std::string print_buffer){ user defined comparison function }, [](<args>){ whatever_function(<args>); })
CHECK_EQUAL(X, Y)
: This macro will check whether two inputs equal
each other and fail the test but allow the rest of the test to
continue.
REQUIRE_ASSERT(...)
: This macro will check whether a particular
assert has occured and flag the tests as failed and halt the test on
failure. This is called either by
REQUIRE_ASSERT("<assert message>", [](<args>){ whatever_function(<args>); })
REQUIRE_ASSERT([](std::string msg){ user defined comparison function }, [](<args>){ whatever_function(<args>); })
REQUIRE_PRINT(...)
: This macro will check whether the print buffer
holds the string that is expected and flag the tests as failed and
halt the test on failure. This is called either by
REQUIRE_PRINT("<print message>", [](<args>){ whatever_function(<args>); })
REQUIRE_PRINT([](std::string print_buffer){ user defined comparison function }, [](<args>){ whatever_function(<args>); })
REQUIRE_EQUAL(X, Y)
: This macro will check whether two inputs X and
Y equal eachother and fail the test and halt the test on failure.
EOSIO_TEST_BEGIN(X)
: This macro defines the beginning of a unit
test and assigns X as the symbolic name of that test.
EOSIO_TEST_END
: This macro defines the end of a unit test.
EOSIO_TEST(X)
: This is used to run a particular named unit test X
in the main function.
clang
org++
. He only shows how to set up the environments in his IDE correctly so that you can compile witheosiocpp
– Phillip Hamnett - EOS42♦ Jul 26 '18 at 7:37eosiocpp
no? – confused00 Jul 26 '18 at 8:32